How to include d3.js in angularjs app? - javascript

I am writing one Angularjs app. I am using MEAN stack with Grunt. I have written one directive that uses d3 library. I have d3.js file in the following location:
/client/app/lib/d3.js
The file is automatically included in the index.html and it runs fine in development mode. But when I run it in production mode I get the following error:
Uncaught ReferenceError: d3 is not defined
Then I did some R&D and found that if any java script file is included with the following syntax it gives same error:
!function foo() {
var myd3 = {};
...
...
...
this.myd3 = myd3;
}();
The above code will give error: Uncaught ReferenceError: myd3 is not defined

If you don't return anything from a function explicitly, undefined is returned. Now the ! makes it true. That's all.
I think the problem is execution of scripts. Are you sure that d3 is loaded first before it is utilized anywhere in your project ? Make sure <script src='d3.js'></script> is present before your code scripts.
Generally, for production grade code, concatenation of scripts is done. Make sure that the concatenation is done in order (d3, your-app-scripts).

Related

How to implement the polylabel function in javascript?

I need to calculate the center (or rather the visible/inner centroid - this is a problem with U-shaped polygons) of a complex polygon, so i found this library called "polylabel" by mapbox on github.
Link: https://github.com/mapbox/polylabel
The problem is that there aren't any instructions on how to implement this on a local html file, where i stored my geojson object inside the javascript section.
I tried making a new js file, copying the code found on github inside of it and then importing it into the hmtl file but i get this error:
polylabel.js:3 Uncaught ReferenceError: require is not defined
at polylabel.js:3:13
(anonymous) # polylabel.js:3
polylabel.js:35 Uncaught TypeError: Queue is not a constructor
at polylabel (polylabel.js:35:21)
at parceleTest.html:85:33
this leads me to believe that polylabel is a node.js function so it is supposed to run on the server side, but i'm still very new to this and very confused, can someone tell me how to call this function in my local javascript?
i also tried using this version:
<script src="https://bundle.run/#mapbox/polylabel#1.0.2"></script>
but it doesn't work or i'm missing something.
Thanks.

Dynamically import d3.js as module?

Trying to dynamically import ("lazy-load") d3 as module from within my existing module to make it self-reliant, as per the es6 syntactic feature (https://developers.google.com/web/updates/2017/11/dynamic-import#dynamic). The source at https://d3js.org/d3.v5.min.js includes no "export" statement, only a literal function call (
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n(t.d3=t.d3||{})}(...)
), yet it does get retrieved, only it doesn't receive its parameters it would expect from a normal <script src="https://d3js.org/d3.v5.min.js"/> tag import. How do I manually provide them, or how am I rather supposed to do this? thanks!
import('https://d3js.org/d3.v5.min.js').then(function(d3){d3.json()})
d3.v5.min.js:2 Uncaught (in promise) TypeError: Cannot read property 'd3' of undefined
at d3.v5.min.js:2
My first guess was wrong...
This error happens because this build of d3 is trying to read this.d3 (the function argument that receives this is called global, or t in the minified version), but this is undefined in a module context (which a script runs in when imported).
It is simply a bug in whatever build tool is used to produce this d3 build. It should use self (or perhaps this || self).
rollup for example used to have this bug but it was fixed a while ago.
Regardless, even after d3 is fixed, you won't get anything in .then(), it will set the d3 global. (Unless they release an ES module build.)

How to solve 'window is not defined' Error in Node JS on Terminal

I want to include angular JS Using require so I am using below code
var ang = require('angular');
But It displays error
ReferenceError: window is not defined
I Know window object not defined in node console but help me how to avoid this error ?
I hope my question understandable.
The window object is only defined in the browser, and isn't defined within Node.js (which uses process instead).
The reason you're getting this error is because you're trying to require a module (angular.js) that was intended to be used with the DOM from a browser, and not within the Node.js environment.
If you want to include angular in your HTML code, include it like you would any other JS file using a tag.

What could cause errors in combined javascript that runs fine when loaded separately?

I've written a server-side utility that is meant to manage javascript page dependencies. During development, it serves the javascript as separate files (embeds individual script tags in the order defined), and in production mode it reads the files, minifies them (Google Closure in Whitespace only mode), and embeds them via a single script tag.
For the moment, I've turned off minification to eliminate that variable...so all it is doing is joining the files together with a newline between each.
When I go to production mode, I get spurious problems in a number of the files that are embedded.
So, does anyone have any ideas of what problems I could be causing by serving a set of files as a single, concatenated file? I'm at a loss.
For those wanting more detail:
I am certain the order is correct.
The list of files in question is rather large for this example, but include jquery, angular, controllers, jquery dnd fileupload, controllers, etc.
I get "Uncaught Type Error: undefined is not a function" at this line of the combo:
(function(b){b.support.touch="ontouchend" in document;if(!b.support.touch){return;}var c=b.ui.mouse.prototype,e=c._mouseInit,a;function d(g,h){if(g.originalEvent.touches.length>1){return;}g.preventDefault();var i=g.originalEvent.changedTouches[0],f=document.createEvent("MouseEvents");f.initMouseEvent(h,true,true,window,1,i.screenX,i.screenY,i.clientX,i.clientY,false,false,false,false,0,null);g.target.dispatchEvent(f);}c._touchStart=function(g){var f=this;if(a||!f._mouseCapture(g.originalEvent.changedTouches[0])){return;}a=true;f._touchMoved=false;d(g,"mouseover");d(g,"mousemove");d(g,"mousedown");};c._touchMove=function(f){if(!a){return;}this._touchMoved=true;d(f,"mousemove");};c._touchEnd=function(f){if(!a){return;}d(f,"mouseup");d(f,"mouseout");if(!this._touchMoved){d(f,"click");}a=false;};c._mouseInit=function(){var f=this;f.element.bind("touchstart",b.proxy(f,"_touchStart")).bind("touchmove",b.proxy(f,"_touchMove")).bind("touchend",b.proxy(f,"_touchEnd"));e.call(f);};})(jQuery);
which follows some other file embeds that generate global vars:
var FocusElementDirective = function() {
...
}
var DirectiveApplier = function(){
...
}
var AgeCalculator = function(){
...
}
Another one: when I trigger an "add" event in the angular plugin for jquery fileupload, it gives Uncaught TypeError: Object # has no method 'scope'. The line it is pointing to is within the jquery fileupload angular module (line 89 of version 9.0.5):
add: function (e, data) {
if (e.isDefaultPrevented()) {
return false;
}
var scope = data.scope(), // this line
Just happening upon this and the first thing that comes to mind is that it could be something to do with global variables, one of those things Crockford complains about as a weakness of javascript.
For a quick description:
JavaScript global variables & self-invoking anonymous functions
Just off the top of my head.
So, I found it, and it turned out to be something ultra-simple...so simple that I pulled my hair out for hours looking for something technical:
I had a duplicate.
When loaded as tags, the browser only bothered to load the file once. When concatenated, the code was actually duplicated. This led to all sorts of weirdness (e.g. event handlers were getting hooked to the wrong version of things).
Coming from a compiled language background, I kinda would expect some duplicate symbol kinds of notifications...ah dynamic languages.

Symfony 2 - Assetic JavaScript compression causing errors

I'm trying to put a Symfony 2 app in production mode. It all runs fine except for the fact that the compressed single JavaScript file causes errors and makes the site unable to render correctly. I found this through the debug console on the browser:
Uncaught TypeError: undefined is not a function
Uncaught TypeError: Object [object Object] has no method 'treeview'
The first error refers to jQuery plug-ins
The treeview refers to a plugin for jQuery which renders a tree like directory structure.
On the other hand, it all runs fine on dev mode cause it doesn't do the compression and it just includes every file one by one. Can someone help me on this one?
I've found a solution to this, it appears the issue is related to missing semi-colons.
When something is the last statement in a js file a semi-colon isn't required however assetic just joins the files together and only adds a new line.
Check the file which is being included just before the broken plugin javascript and make sure it ends with a semicolon.

Categories