angular2-materialize: sideNav throws $(...).velocity or menu_id.velocity is not a function

Similar to issue #5 . I have updated my webpack config to the recommended settings:

        alias : {
            materializecss: 'materialize-css/dist/css/materialize.css',
            materialize: 'materialize-css/dist/js/materialize.js',
            jQuery: 'jquery', // I tried this and it didn't change anything
            $: 'jquery'  // I tried this, too, and it didn't change anything
        }

I also found I had to install stylus/stylus-loader because webpack was complaining about not being able to understand .styl files

            test: /materialize\.css$/, loader:
            'style-loader!css-loader'
        }, {
            test: /\.styl$/,
            loader: 'style!css!stylus-loader'
        }
    var cssLoader = {
            test : /^((?!materialize).)*\.css$/,
            // Reference: https://github.com/webpack/extract-text-webpack-plugin
            // Extract css files in production builds
            //
            // Reference: https://github.com/webpack/style-loader
            // Use style-loader in development for hot-loading
            loader : ExtractTextPlugin.extract('style', 'css?sourceMap!postcss')
new webpack.ProvidePlugin({
            $ : "jquery",
            jQuery : "jquery",
            jquery: 'jquery',
            'window.$': 'jquery',
            "window.jQuery": 'jquery',
            "root.jQuery": 'jquery',
            Hammer : "hammerjs/hammer"
        })

My component:

import { Component, OnInit, ElementRef } from 'angular2/core';
import { TodoContext } from './todo-context';
import { TodoContextService } from './todo-context.service';
import { MaterializeDirective } from 'angular2-materialize';
import 'material-icons/css/material-icons.min.css';

let template = `
                <a materialize="sideNav" href="#" data-activates="nav-mobile" class="button-collapse"><i class="material-icons">menu</i></a>
                <ul id="nav-mobile" class="side-nav fixed">
                    <li class="bold" *ngFor="#context of contexts"><a href="#!">{{context.name}}</a></li>
                </ul>
                <ul id="slide-out" class="side-nav">
                    <li class="bold" *ngFor="#context of contexts"><a href="#!">{{context.name}}</a></li>
                </ul>

`;


@Component({
    selector: 'todo-context',
    directives: [MaterializeDirective],
    template: template,
    styles: [`
        header, main, footer {
            padding-left: 240px;
        }

        @media only screen and (max-width : 992px) {
            header, main, footer {
                padding-left: 0;
            }
        }
        `]
})
export class TodoContextComponent implements OnInit {
    contexts: TodoContext[] = [];

    constructor(private _todoContextService: TodoContextService) { }

    ngOnInit() {
        this._todoContextService.getTodoContexts()
            .then(contexts => this.contexts = contexts);
    }
}

When I make the page smaller to expose the menu icon on the sidenav, and click the menu icon, I see the following in the console

BrowserDomAdapter.logError @ browser_adapter.ts:73ExceptionHandler.call @ exception_handler.ts:52(anonymous function) @ application_ref.ts:258schedulerFn @ async.ts:127SafeSubscriber.__tryOrUnsub @ Subscriber.js:166SafeSubscriber.next @ Subscriber.js:115Subscriber._next @ Subscriber.js:74Subscriber.next @ Subscriber.js:51Subject._finalNext @ Subject.js:124Subject._next @ Subject.js:116Subject.next @ Subject.js:73EventEmitter.emit @ async.ts:113NgZone._zoneImpl.ng_zone_impl_1.NgZoneImpl.onError @ ng_zone.ts:134NgZoneImpl.inner.inner.fork.onHandleError @ ng_zone_impl.ts:88ZoneDelegate.handleError @ angular2-polyfills.js:394Zone.runTask @ angular2-polyfills.js:323ZoneTask.invoke @ angular2-polyfills.js:490
browser_adapter.ts:73 TypeError: menu_id.velocity is not a function
    at HTMLAnchorElement.eval (webpack:///./~/materialize-css/dist/js/materialize.js?:2305:25)
    at HTMLAnchorElement.jQuery.event.dispatch (webpack:///./~/jquery/dist/jquery.js?:4737:27)
    at HTMLAnchorElement.elemData.handle (webpack:///./~/jquery/dist/jquery.js?:4549:28)
    at ZoneDelegate.invokeTask (webpack:///./~/angular2/bundles/angular2-polyfills.js?:423:38)

whole bunch of other stuff

I believe this issue is because materialize does some loading before jquery and it’s dependencies are all wired up. Looking at my webpack output, I would expect to see jquery/hammer loaded before materialize, correct? But this isn’t the case:

    [0] ./src/index.ts 280 bytes {0} [built]
    [1] ./~/jquery/dist/jquery.js 259 kB {0} [built]
    [2] ./~/materialize-css/dist/js/materialize.js 281 kB {0} [built]
    [3] (webpack)/buildin/amd-options.js 43 bytes {0} [built]
    [4] ./~/hammerjs/hammer.js 71.6 kB {0} [built]
    [5] ./~/materialize-css/dist/css/materialize.css 897 bytes {0} [built]
    [6] ./~/css-loader!./~/materialize-css/dist/css/materialize.css 158 kB {0} [built]
    [8] ./~/materialize-css/dist/fonts/roboto/Roboto-Thin.eot 82 bytes {0} [built]

Does anyone have any ideas on how to fix this? I tried the solution in #5 but to no avail.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 33 (9 by maintainers)

Most upvoted comments

Guys,

I don’t know if this is the best solution but got it solved here:

1 - import the jquery.min.js in index.html <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>

2 - on webpack.conf.js add these lines:

  externals: {
    jquery: 'jQuery'
  },

Hope this solve the issue for you all using webpack.

Cheers!

I think I found something. Webpack isolates jQuery and for some reason MaterializeCSS needs a window.jQuery object. So, i’ve added the following config in webpack to solve the problem (Notice the creation of window.jQuery in there, to provide MaterializeCSS with what it expects):

    new webpack.ProvidePlugin({
        $: "jquery",
        jQuery: "jquery",
        "window.jQuery": "jquery",
        Hammer: "hammerjs/hammer"
    }),

@tomgeorge @enmanuelr are you able to confirm if this solves the issue for you?

To solve this is used the jquery version that is located in the materialize folder

window.$ = window.jQuery = require(‘materialize-css/node_modules/jquery/dist/jquery.js’); require(‘materialize-css’);

I’ve also tried to implement ngAfterViewInit and attempt the jQuery setup manually:

import { Component, AfterViewInit, Directive}       from 'angular2/core';
...

declare var $: any
...

export class AppComponent implements AfterViewInit {

    title = 'gttd';

    constructor (private elementRef: ElementRef) {
    }

    public ngAfterViewInit() {
        $('.button-collapse').sideNav();
    }
}

Might try tinkering with the imports loader next.

Hey @TheThingRus thanks, it solved my issue. Also this link was helpful.

@akashbiz have you tried to add next code in the config file of the webpack? new webpack.ProvidePlugin({ //$: “jquery”, //jQuery: “jquery”, “window.jQuery”: “jquery”, //Hammer: “hammerjs/hammer” }),

The problem: your app isn’t seeing jquery module.

@rubyboy Great THANK YOU!! 5 hours!

My fix: new webpack.ProvidePlugin({ //$: “jquery”, //jQuery: “jquery”, “window.jQuery”: “jquery”, //Hammer: “hammerjs/hammer” }),

#webpack #webpack2 #materialize #materializecss #velocity

I just did yarn add jquery and it fixed.

Here’s a repository that reproduces the same problem using the latest angular2-webpack-starter: https://github.com/rubyboy/angular2-webpack-starter Getting “newTooltip.velocity is not a function”

CC @snarum @denneulin , having the same problem.

@Dogfalo any tips on this?