I'm trying to run vis.js in an Angular4 project configured with Angular-cli that is already using Materialize-css
When running the angular application I get this error in console :
Uncaught TypeError: Hammer.assign is not a function
at propagating (vis.js:37731)
at Object.<anonymous> (vis.js:1915)
at __webpack_require__ (vis.js:57)
at Object.<anonymous> (vis.js:34498)
at __webpack_require__ (vis.js:57)
at Object.<anonymous> (vis.js:28975)
at __webpack_require__ (vis.js:57)
at exports.__esModule (vis.js:100)
at vis.js:103
at webpackUniversalModuleDefinition (vis.js:30)
In package.json :
"vis": "4.21.0",
"jquery": "^2.2.4",
"hammerjs": "^2.0.8",
"materialize-css": "^0.100.2",
"angular2-materialize": "^15.1.10",
In angular-cli.json
"styles": [
"../node_modules/materialize-css/dist/css/materialize.css",
"../node_modules/vis/dist/vis.min.css",
"assets/scss/main.scss"
],
"scripts": [
"../node_modules/jquery/dist/jquery.js",
"../node_modules/hammerjs/hammer.js",
"../node_modules/materialize-css/dist/js/materialize.js",
"../node_modules/vis/dist/vis.min.js"
],
I check that hammerjs, jquery, vis and materialize and correctly installed and present in /node_modules
directory
hammerjs, jquery and materialize were already installed and working in the project. Which is a simple web site.
Any idea what could lead to this error and how to correct it ?
This is a very difficult question to answer as you don't provide a Minimal, Complete, and Verifiable example.
It would seem from your question that you are having trouble getting the vis.js
library to work in an Angular 4 application. Getting vis.js
to work in Angular 4 is quite straightforward. Here are the steps I followed:
ng new ng-vis
npm install --save vis @types/vis
.angular-cli.json
file add "../node_modules/vis/dist/vis.css"
to the styles array(as you have shown above)Add vis to a view/view-model
src/app/app.component.html
to <div #vis></div>
I then updated src/app/app.component.ts
to the following
import { Component, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
import * as vis from 'vis';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
@ViewChild('vis') element: ElementRef;
network: vis.Network;
ngAfterViewInit(): void {
const nodes = new vis.DataSet([
{id: 1, label: 'Node 1'},
{id: 2, label: 'Node 2'},
{id: 3, label: 'Node 3'},
{id: 4, label: 'Node 4'},
{id: 5, label: 'Node 5'}
]);
const edges = new vis.DataSet([
{from: 1, to: 3},
{from: 1, to: 2},
{from: 2, to: 4},
{from: 2, to: 5}
]);
const data = {
nodes: nodes,
edges: edges
};
const options = {};
this.network = new vis.Network(this.element.nativeElement, data, options);
}
}
You seem to be manually adding your external scripts to the .angular-cli.json
file which I would think wouldn't be a best practice. Through utilizing Typescript, you will get the explorability of its type system as well as a few other benefits. The types and certain annotations are what allows Angular to help manage loading of dependencies(possibly the cause of the problem you are describing above) and allows the build system to make smarter decisions when it performs AOT and tree-shaking.
UPDATE
As per Ramesh Rajendran's comment, it is possible that the error is coming from utilizing both materialize-css
and vis.js
in the same project. From his comment, and the referenced GitHub issue, it would see you should just have to update your .angular-cli.json
file to have the following scripts:
"scripts": [
"../node_modules/vis/dist/vis.min.js",
"../node_modules/jquery/dist/jquery.js",
"../node_modules/hammerjs/hammer.js",
"../node_modules/materialize-css/dist/js/materialize.js
]
Again I would caution you against this approach as it doesn't seem to be in line with best practices. I updated my example to work with both materialize-css
and vis.js
as follows:
npm install --save materialize-css @types/materialize-css
Update app.component.html
<div #vis></div>
<ul #collapse class="collapsible" data-collapsible="accordion">
<li>
<div class="collapsible-header"><i class="material-icons">filter_drama</i>First</div>
<div class="collapsible-body"><span>Lorem ipsum dolor sit amet.</span></div>
</li>
<li>
<div class="collapsible-header"><i class="material-icons">place</i>Second</div>
<div class="collapsible-body"><span>Lorem ipsum dolor sit amet.</span></div>
</li>
<li>
<div class="collapsible-header"><i class="material-icons">whatshot</i>Third</div>
<div class="collapsible-body"><span>Lorem ipsum dolor sit amet.</span></div>
</li>
</ul>
Update `app.component.ts'
import { Component, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
import * as vis from 'vis';
import * as $ from 'jquery';
import 'materialize-css';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements AfterViewInit {
@ViewChild('vis') element: ElementRef;
@ViewChild('collapse') c_element: ElementRef;
network: vis.Network;
ngAfterViewInit(): void {
const nodes = new vis.DataSet([
{id: 1, label: 'Node 1'},
{id: 2, label: 'Node 2'},
{id: 3, label: 'Node 3'},
{id: 4, label: 'Node 4'},
{id: 5, label: 'Node 5'}
]);
const edges = new vis.DataSet([
{from: 1, to: 3},
{from: 1, to: 2},
{from: 2, to: 4},
{from: 2, to: 5}
]);
const data = {
nodes: nodes,
edges: edges
};
const options = {};
this.network = new vis.Network(this.element.nativeElement, data, options);
$(this.c_element.nativeElement).collapsible();
}
}