Issue loading the backbone view for the first time - javascript

I want to load one of my javascript automatically on the load of my html page.
The html page on load of which I want to load my js file.
<!DOCTYPE html>
<html>
<head>
<script src="/static/js/LoginApp.js"></script>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<div class="container">
<h1>Backbone Tutorial Blogroll App</h1>
<button type="button" id="newButton">Click Me!</button>
<script src="/static/js/require.js"></script>
<script src="/static/js/LoadView.js"></script>
</div>
</body>
</html>
The javascript I want to load is
LoadView.js
define([
'jquery',
'underscore',
'backbone',
'LoadView',
'text!NewViewCheck.html',
], function($, _, Backbone, LoadView, NewViewCheck) {
var Task = Backbone.Model.extend({
defaults: {}
});
TheView = Backbone.View.extend({
model: new Task(),
events: {
'click #newButton': 'initializeView',
},
//'template' provides access to instance data when rendering the view
template: _.template(NewViewCheck),
initialize: function() {
console.log('Inside the initialize function');
this.render();
},
render: function() {
//this.$el.html(this.template());
console.log(labelsLocale);
this.$el.html(this.template({}));
$('#dialogContent').empty().append(this.$el);
$('#addUserDefinedOption').modal('show');
},
initializeView: function() {
var theView = new TheView();
console.log('abc');
},
});
$(document).ready(function() {
//console.log('abc');
})
});
I am getting the following error
Uncaught Error: Mismatched anonymous define() module
Please help me thanks in advance.

The error is because you have:
<script src="/static/js/LoadView.js"></script>
The docs says:
If you manually code a script tag in HTML to load a script with an anonymous define() call, this error can occur.
And that's what you're doing.
And in solutions:
Be sure to load all scripts that call define() via the RequireJS API. Do not manually code script tags in HTML to load scripts that have define() calls in them.
If you manually code an HTML script tag, be sure it only includes named modules, and that an anonymous module that will have the same name as one of the modules in that file is not loaded.
So simply load it using requireJS from your main file or name the module

Related

Dojo AMD not loading custom module

I'm trying to make a web application using the ArcGIS API, Dojo, and Flask. I want to start by making a "file uploads" dialog, which I am trying to define as its own module using the Dojo 1.7 AMD convention (i.e. "define").
Here is my file structure:
\static
home.js
fileUpload.js
\templates
home.html
main.py
Here is the code for the dialog (copied from one of the Dojo Tutorials). I am basically trying to put all dialog related function (i.e. show and hide) in one module:
define([
"dijit/registry",
"dijit/Dialog",
"dijit/form/Button",
"dojo/ready",
"dojo/domReady!"
], function (registry) {
console.log("HELLO WORLD");
return {
// Show the dialog
showDialog: function() {
registry.byId("uploads").show();
},
// Hide the dialog
hideDialog: function() {
registry.byId("uploads").hide();
}
}
});
At the end of "home.js" I try to create and instance of the dialog module:
var fu = new fileUpload();
Then in my "home.html" file, I define the actual dialog and try to use the "fu" object's variables as event handlers for closing and opening the dialog:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<title>morPOP</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
<link rel="stylesheet" href="https://js.arcgis.com/4.5/esri/css/main.css">
<link rel="stylesheet" href="../static/css/home.css">
<script src="https://js.arcgis.com/4.5/"></script>
<script src="../static/js/home.js"></script>
</head>
<body>
<!-- Map -->
<div id="viewDiv"></div>
<!-- Upload Button -->
<div class="btn-toolbar" role="toolbar" aria-label="Toolbar with button groups">
<button type="button" id="uploadbtn" class="btn btn-primary" onclick="fu.showDialog()">Upload</button>
</div>
<!-- Upload Dialog -->
<div class ="dijitHidden">
<div id="uploads" data-dojo-type="dijit/Dialog" data-dojo-props="title:'Upload Files'">
<p>The following files must be uploaded to run a simulation. File names must match those listed below.</p>
<p>Acceptable file extensions: .txt or .csv</p>
<ul>
<li>Geographic data</li>
<ul>
<li>Age_Dissemination</li>
</ul>
<li> Probability Data </li>
<ul>
<li>ageContactDuration_hospital_nurse</li>
<li>ageContactDuration_hospitalPatient</li>
<li>ageContactNumber_hospital</li>
</ul>
<li> ??? </li>
<ul>
<li>Census_Division_Mapping</li>
</ul>
</ul>
<button onclick="fu.hideDialog();">Finish</button>
</div>
</div>
</body>
</html>
The error that I get in the google Chrome developer console is the following:
Uncaught TypeError: Cannot read property 'on' of undefined
at new g (init.js:56)
at home.js:51
at Q (init.js:18)
at init.js:18
at A (init.js:18)
at ea (init.js:18)
at d (init.js:20)
at HTMLScriptElement.<anonymous> (init.js:23)
I'm not sure what "on" property the error is referring to. Does anyone have any ideas? Why can't I declare an instance of my module?
** EDIT ***
I've changed my home.js file to "require" fileUpload.js, but I am now getting the following error when I try to click the "submit" button:
(index):24 Uncaught ReferenceError: fu is not defined
at HTMLButtonElement.onclick ((index):24)
Please see the following plunkr for my updated home.js file: https://plnkr.co/edit/9dFVHsFOCji1aE0ZeLRQ?p=preview
When using AMD you manage your dependencies by defining things as you have done with define() but client of module must import it using require() function, see docs, meanwhile you try to instantiate required module via new which is not correct.
To use some module in DOM handler you need extra wrapper e.g. your HTML would make onclick="whenClicked()" if you have this function in scope:
function whenClicked() {
require(['fileUpload'], function(fu) {
fu.showDialog();
});
}
assuming of course that 'fileUpload' is correctly specified AMD module.
EDIT: modified version of OP sample on Plunker:
https://plnkr.co/edit/QFckwndDicGpTfzhGwFC?p=preview
Note fileUpload.js module definition changed so that basic alert is displayed:
define([
"dijit/registry",
"dijit/Dialog",
"dijit/form/Button",
"dojo/domReady!"
], function (registry) {
return {
// Show the dialog
showDialog: function() {
//registry.byId("uploads").show();
alert("this is file upload mock");
}
}
});
as well as home.js hosting definition of whenClicked:
function whenClicked() {
require({
packages: [
{name: "fileUpload",
// location should point to fileUpload.js on your target server
location: "https://run.plnkr.co/uv2ILkhQpQC2wqRV",
main: "fileUpload"}
]},
['fileUpload'], function(fu) {
console.log("fileupload");
fu.showDialog();
});
}
Note that showing location of module is similar to what bRIMOs said in other answer. My approach configures however location only for this particular code wrapped by require; approach of bRIMOs is global.
Be aware however that Plunker is rebuilding location URL each time you reload editor :/ it effectively means tha you fix location prefix, run it fine, reload Plunker page, and it is broken again.
I think you missed to configure the path in dojo config in order to access the fileupload.js file by the AMD loader , In the dojoConfig doc there is many type of config ( basURl ,package , paths ...) , below you can see how to make configuration using packges , and dojo will load you files using require without any problem
So before loading your arcgis js api <script src="url_api_js"></script> be sur to do the folowing (configuring dojo with dojoConfig var)
<script type="text/javascript">
var dojoConfig = {
packages: [
{
name: "mypackage",
location: location.pathname.replace(/[^\/]+$/, '') +"/static"
}
]
};
<script>
<script src="url_api_js"></script>
and the inside your code use the name of package/name of file as below
require(['mypackage/fileUpload'], function(upload) {
upload.showDialog();
});
NB: the location could change , according to the server type , in this exemple the location is like : {location_name}/static/fileupload.js
hopefully this would help you .

RequireJS, jquery still undefined

I know this has already been discussed, but after searching for a while I can't figure out why my small setup does not load jquery correctly with requireJS.
I'm running a small sample html page from 'file://' and try to load 2 modules with a call to require:
jquery
a custom module I wrote
If my custom module loads correctly (i can use it with its alias in the require call, jquery is always undefined)
I tried to setup paths in require.config, as well as shim (exporting '$' or 'jQuery') but it does not work.
The only way i can get jquery to correctly load, is removing all paths definition and naming the jquery file on my filesystem 'jquery.js'
Here is my config:
main.js:
require.config({
baseUrl: 'scripts',
paths: {
jquery: 'jquery-2.1.3.min' //does not work
//jquery: 'http://code.jquery.com/jquery-2.1.3.min.js' //does not work either
}
});
console.log( "main.js is loaded" ); //this is correctly ouputed to the console
test.html:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<!--
... page content ...
-->
<!-- main.js is loaded from data-main -->
<script data-main="scripts/main" src="scripts/require.js"></script>
<script type='text/javascript'>
require(
['jquery','custom'],
function($, Custom){
console.info('$:');
console.info($); //outputs undefined
console.info('Custom:');
console.info(Custom); //outputs my custom object
});
</script>
</body>
</html>
Once again, it works if I remove all paths definition for jquery, and simply name my jquery js file 'jquery.js' but this is sloppy.
Can somebody points me on the right way to go ?
The problem is that you load your RequireJS configuration, which is in main, through data-main. The data-main attribute merely tells RequireJS to load the module listed there but the loading is still asynchronous, so main may load after RequireJS tries to load jQuery. When this happens, RequireJS fails to find jQuery and $ is undefined. (Incidentally, I'd suggest setting enforceDefine to true in your RequireJS configuration so that you get an error message telling you when a module has not loaded. That's a better clue than having an undefined symbol.)
One solution would be to move your configuration outside of main. So you remove it from main and add it to a script element in front of the one loading RequireJS:
<script>
// RequireJS will use the value of `require` as its configuration.
require = {
baseUrl: 'scripts',
paths: {
jquery: 'jquery-2.1.3.min'
},
enforceDefine: true
};
</script>
<script src="scripts/require.js"></script>
Or you can nest require calls to force main to load before any other module:
require(['main'], function () {
require(['jquery','custom'], ...
});

Requirejs and external scripts

Hi I have my js application that was built with requirejs. Now I have external page from other developer, he can load his scripts, html, css and other things that not connected to me.
Here example of my module that will be connected to his page:
require(['page', 'widgetGame', 'adDynamic'], function (Page, WidgetGame, AdDynamic) {
function PageExternalGame (params) {
var params = params || {};
Page.call(this, params); // call super constructor.
};
PageExternalGame.prototype.gameLoadingComplete = function() {
alert(111);
};
window.yepiExternalPageGame = new PageExternalGame();
return PageExternalGame;
});
and here example of his page:
<!DOCTYPE HTML>
<html lang="en"><head>
</head>
<body>
<div id='gameArea'>
<canvas id='canvas0' width='480' height='320' style="position: absolute; "></canvas>
</div>
<script data-main="../../YepiMobileNew/UI/js/pageExternalGame" src="http://requirejs.org/docs/release/2.1.14/minified/require.js"></script>
<script src='js/gamemin.js'></script>
<script>yepiExternalPageGame.gameLoadingComplete()</script>
</body>
</html>
So in his page he call my object yepiExternalPageGame, that should be loaded by requirejs. but when he call this object, require itself already loaded, but class pageExternalGame still wasn't loaded, so this object is not exist when he call it. How to handle with it? (His outer scripts also can call my object). Thanks.
Firstly if you sharing your amd app with other it is good to create build that isn't using require.js so you won't force other developers to add another lib and increase page size. You can do this with almond.js
But returning to your question.
Change
<script>yepiExternalPageGame.gameLoadingComplete()</script>
to
<script>
require(['../../YepiMobileNew/UI/js/pageExternalGame'], function() {
yepiExternalPageGame.gameLoadingComplete();
});
</script>
That will help.

Why is my javascript file not loading?

I'm new to both JavaScript & AngularJS. I'm building an app which talks to a building management system: it has a module called 'JaceMod' containing a service to contact the BMS and retrieve data from it. I'm adding functionality to graph data using Dygraphs, and I've created a directive to instantiate a graph and populate it with data.
I would like to put my Dygraphs directive into a module called 'dygraphs', in a separate file 'angular-dygraphs.js', so I can re-use it later, and require this module as a dependency in 'JaceMod'. Like this:
'use strict';
console.log('Loading angular-dygraphs.js');
angular.module('dygraphs', []);
angular.module('dygraphs').directive('mrhDygraph', function ($parse) {
return {
...etc ...
};
});
And then the main file 'app.js':
'use strict';
console.log('Loading app.js');
angular.module('JaceMod', ['dygraphs']);
angular.module('JaceMod').factory('JaceData', function ($http, $timeout) {
var JaceDataService = {};
...etc ...
return JaceDataService;
});
angular.module('JaceMod').controller('myCtrl', function myCtrl($scope, JaceData) {
JaceData.initialise($scope);
JaceData.subscribe($scope);
});
The html looks like this:
<html lang="en" ng-app="JaceMod">
<head>
<meta charset="utf-8">
<title>AngularJACE</title>
<style type="text/css">
body {font-family: Trebuchet MS,Helvetica,Arial,sans-serif; }
</style>
</head>
<body ng-controller="myCtrl">
<div mrh-dygraph="graphData"
mrh-dygraph-options="{xlabel: 'Local Time', legend: 'always',
showRangeSelector: true, labels: ['Time', 'Outside'],
ylabel: 'Temperature (ÂșC)', height: 420}"
style="width: 100%; height 420px;"/>
<script src="dygraph-combined.js"></script>
<script src="angular.js"></script>
<script src="angular-dygraphs.js"/>
<script src="app.js"></script>
</body>
But when I load this html, I see my console message 'Loading angular-dygraphs.js', followed by an eror 'Error: No module: JaceMod'. I never see the log message in app.js. If I switch the load order of the last 2 javascript files round, I see that app.js loads and the error message is 'Error: No module: dygraphs'. The second listed file seems never to be loaded.
If I copy the code from angular-dygraphs.js into app.js, leaving the directive in its own module, it works.
Why is this happening? Is it not possible to put modules in their own files, or something? The documents haven't been much help...
EDITED TO ADD
The html & js files are all in the same directory, including the dygraphs & angular libraries. I'm loading the html from file, no server involved.
UPDATE
I copied everything from angular-dygraphs.js into app.js, and commented out the entirety of angular-dygraphs.js: still getting the problem, app.js does not load.
Your angular-dygraphs.js script tag isn't closed so it never reads app.js. Script tags cannot be self-closing:
<script src="angular-dygraphs.js"/>
should be
<script src="angular-dygraphs.js"></script>

Adding dojo widget inside custom widget

I am making a small dojo widget, basically extending the dailog widget and want to add simple widgets like a text input a few labels etc. How do i go about this? I am following a tutorial,
Dojo how to make a widget
Please help me out.
Thanks
First. I'am not good at english, but will do at my best.
This is the path of my widget.
Here. The important code in the js file that must declare.
dojo.provide("gissoft.dijit.widgetOam");
dojo.require("dojo.parser");
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.declare("gissoft.dijit.widgetOam", [dijit._Widget, dijit._Templated], {
widgetsInTemplate: true,
basePath: dojo.moduleUrl("gissoft.dijit"),
templatePath: dojo.moduleUrl("gissoft.dijit", "templates/widgetOam.html"),
constructor: function () {
},
postMixInProperties: function () {
},
postCreate: function () {
},
startup: function () {
}
});
And in file widgetOam.html(templatePath)
<div> <!-- do not add tag <html> , <head> , <body> but must have <div> first -->
Hello World.
</div>
And this is how to call widget from my Default.aspx
You must add this before you call the dojo library
<script>
djConfig = {
parseOnLoad: true,
baseUrl: './',
modulePaths: { 'gissoft.dijit': 'js/gissoft/dijit' }
};
</script>
And in the body
<body class="tundra">
<form id="form1" runat="server">
<div>
<div data-dojo-type="gissoft.dijit.widgetOam"></div>
</div>
</form>
</body>
If I understood correctly, you are asking about how to include another widgets within your custom widget. If that's the case, then we have to modify OammieR's answer a bit, as it's not complete in regards to your question.
To include other widgets within your custom widget, you should include them in your widget declaration:
dojo.provide("gissoft.dijit.widgetOam");
dojo.require("dijit.form.Button"); //<- this the standard widget you want to have in your widget
dojo.require("dojo.parser");
dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.declare("gissoft.dijit.widgetOam", [dijit._Widget, dijit._Templated], {
widgetsInTemplate: true,
basePath: dojo.moduleUrl("gissoft.dijit"),
templatePath: dojo.moduleUrl("gissoft.dijit", "templates/widgetOam.html"),
particularly important is the "widgetsInTemplate: true" part which tells the parser to expect the widgets inside the widget.
Then you just include the HTML markup for the particular widget you'd like to include in your widget's template.
<div> <!-- do not add tag <html> , <head> , <body> but must have <div> first -->
<button data-dojo-type="dijit.form.Button" type="button" data-dojo-attach-point="_innerWidget" data-dojo-attach-event="ondijitclick:_onClick">Yo!</button>
</div>
dojoAttachPoint is useful so you can get a reference to this widget straightaway in your widget's implementation without getting a reference via dijit.byId('').
Hope this helps.

Categories

Resources