Lazy-load MonacoEditor - angularjs

I have the following code to load MonacoEditor in index.html of my AngularJS website:
<link rel="stylesheet" data-name="vs/editor/editor.main" href="/monaco-editor/min/vs/editor/editor.main.css" />
<script src="/monaco-editor/min/vs/loader.js"></script>
<script src="/monaco-editor/min/vs/editor/editor.main.nls.js"></script>
<script src="/monaco-editor/min/vs/editor/editor.main.js"></script>
<script>
require.config({ paths: { 'vs': '/monaco-editor/min/vs' }})
console.log(monaco)
</script>
Running the website displays well monaco, which will be used in a further JavaScript file.
Now, I want to load MonacoEditor by ocLazyLoad:
.state('addin', {
abstract: true,
template: '<ui-view/>',
resolve: {
loadAddinCtrl: ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load({files: [
"/monaco-editor/min/vs/editor/editor.main.css",
"/monaco-editor/min/vs/loader.js",
"/monaco-editor/min/vs/editor/editor.main.nls.js",
"/monaco-editor/min/vs/editor/editor.main.js"
]}).then(function () {
require.config({ paths: { 'vs': '/monaco-editor/min/vs' }})
console.log(monaco)
})
}]
}
})
The above code returns ReferenceError: monaco is not defined. Does anyone know why this happens?
Actually, I don't understand well the purpose of require.config, it seems to make the code much less flexible. Does anyone have an alternative to that?

You have loaded the dependencies, yet not loaded Monaco. Try this after your require.config:
require.config({ paths: { 'vs': '/monaco-editor/min/vs' }})
require(['vs/editor/editor.main'], function onMonacoLoaded(){
console.log(monaco);
});

Related

RequireJS configuration error - jQuery not found when calling Backbone

I'm trying to setup a require js project for learning purposes. I need to run a Backbone app.
Index.html, looks plain and simple:
<!DOCTYPE html>
<html>
<head>
<base href="/" />
<title>RequireJS - Test drive</title>
<!-- data-main attribute tells require.js to load scripts/main.js after
require.js loads. -->
<script data-main="js/main" src="js/vendor/require.js"></script>
</head>
<body>
<h1>RequireJS - Test drive</h1>
</body>
</html>
Currently I have this config in my main.js: (which is the entry point in index.html for requirejs)
require.config({
paths: {
underscore: 'vendor/underscore-1.9.1.min',
jquery: 'vendor/jquery-3.4.1.min',
backbone: 'vendor/backbone-1.4.0.min',
app: 'app/app',
userModel: 'app/models/user.model',
userListView: 'app/views/user-list.view',
userSingleView: 'app/views/user-single.view',
},
bundles: {
'models': ['userModel']
},
shim: {
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'underscore': {
exports: '_'
}
},
});
// Start the app
define(['app'], (App) => {
return App.initialize();
});
In app.js, which I try to initiate the app with, I have the following:
define(['backbone'], (Backbone) => {
const initialize = () => {
console.log('App initialized.', Backbone);
const data = {title: 'title'};
const view = 0; // new View here....
};
return {
initialize: initialize
}
});
Now, if I remove backbone as a dependency, I am able to see the console.log message in the browser. If I leave it there, then the console throws this error:
require.js:5 GET http://127.0.0.1:8080/js/js/vendor/jquery-3.4.1.min.js net::ERR_ABORTED 404 (Not
Found)
require.js:5 Uncaught Error: Script error for "js/vendor/jquery-3.4.1.min", needed by: backbone
https://requirejs.org/docs/errors.html#scripterror
at makeError (require.js:5)
at HTMLScriptElement.onScriptError (require.js:5)
Inspecting the network tab, I can see that the jQuery dependency has errored out, and for some reason an additional /js has been added to the path, which results in a 404 error for jQuery, but only when I try to use Backbone on the app.js file.
Path looks like this, with the additional /js added to it:
http://127.0.0.1:8080/js/js/vendor/jquery-3.4.1.min.js
What is it that I am missing in the configuration/setup of the application?
I believe you should set baseUrl in your config
require.config({
baseUrl: '/js'
});

Require and Angular RouteProvider undefined

I get undefined in the following code when trying to load via require.js
HTML
<script data-main="application/main" src="http://requirejs.org/docs/release/2.1.14/minified/require.js"></script>
main.js
require.config({
baseUrl: "application",
paths: {
angular: 'https://code.angularjs.org/1.4.5/angular',
angularRoute: 'https://code.angularjs.org/1.4.5/angular-route'
},
shim: {
angular: {exports: 'angular' } ,
angularRoute: { deps: ['angular'], exports: 'angularRoute' },
}
});
require(['app', 'routesBoot'], function (app) {
app.init();
});
app.js
define(['angular'], function (angular) {
var app = angular.module('reporterdashboard', []);
app.init = function () {
console.log('app.init called');
angular.bootstrap(document, ['reporterdashboard']);
};
return app;
});
routesBoot.js
require(['app', 'angularRoute'], function (app, angularRouterParam) {
//put my routes in here, using angularRouterParam
//but angularRouterParam = undefined
return app.config(function (angularRouterParam) {
angularRouterParam.when('/page2', { controller: 'Page2Controller', templateUrl: 'page2.html' });
});
});
When I inspect angularRouterParam passed into routesBoot it's undefined. What have I done wrong ?
I'm basically trying to split my app and therefore, placing my routes in their own file (controllers, directives etc will live in their own boot .js files). I'm letting require.js look after all my .js file loading as can be seen in main.js.
The code in routesBoot is not syntactically correct at the moment as I'm stuck with the problem of an undefined angularRouterParam
The problem was out side of the code I've posted here. I was loading a directive first into the index.html (View First). This directive was loading other dependencies. The project is quite large, some 40 .js files. My restructuring with require was at fault.

angular and ui-router example is not working

Hello I'm trying a simple application with Angular and UI-Router...
But for some reason, it's not working at all.
In chrome, there is no error in the console, but there is even no output at all
Maybe some one has some clue on what's happening... I definitely have no idea.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<script src="/Scripts/angular.min.js"></script>
<script src="/Scripts/angular-ui-router.js"></script>
</head>
<body>
<div>
Route 1
<div ui-view="viewSidebar"></div>
<div ui-view="viewContent"></div>
</div>
<script>
var app = angular.module('app', ['ui.router']);
app.config(
['$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/media/list');
$stateProvider.state('mediaList', {
views: {
url: "/media/list",
'viewSidebar': {
template: '<p>SideBar</p>',
controller: 'SidebarControllerView'
},
'viewContent': {
template: '<p>Thumb view</p>',
controller: 'MediaControllerView'
}
}
});
}]);
app.controller('MediaControllerView', ['$scope', MediaControllerView]);
app.controller('SidebarControllerView', ['$scope', SidebarControllerView]);
function MediaControllerView($scope) {
$scope.model = 1;
};
function SidebarControllerView($scope) {
$scope.model = 1;
};
</script>
</body>
</html>
There is a working plunker
One important wrong setting is the URL. It does not belong to the view, but to the state:
...
$stateProvider.state('mediaList', {
// url belongs to the state
url: "/media/list",
views: {
// url does not belong to the views
// url: "/media/list",
'viewSidebar': {
template: '<p>SideBar</p>',
controller: 'SidebarControllerView'
},
'viewContent': {
template: '<p>Thumb view</p>',
controller: 'MediaControllerView'
}
}
});
...
Check it here
And also, as DTing spotted we have to provide ng-app:
<html ng-app="app" ng-strict-di>
...
NOTE: ng-strict-di is not a must but... it is a must - to avoid later issues...
if this attribute is present on the app element, the injector will be created in "strict-di" mode. This means that the application will fail to invoke functions which do not use explicit function annotation (and are thus unsuitable for minification), as described in the Dependency Injection guide, and useful debugging info will assist in tracking down the root of these bugs.

No module and Modernizr error when adding angular to requirejs

Im trying to add AngularJS to my web application which already makes use of RequireJS. When loading my test page, i am seeing:
1) Error: No module: MyApp
...),factory:a("$provide","factory"),service:a("$provide","service"),value:a("$prov...
2) TypeError: Modernizr is undefined
if (!Modernizr.history) {
I am using AngularJS v1.1.5
Here's my tree:
resources
- CSS
- js
- controllers
- MainController.js
- libs
- angular.js
- jquery.js
- require.js
- mondernizr.js
......
......
......
main.js
mainApp.js
pages
test.html
main.js
(function(require) {
'use strict';
require.config({
baseUrl: '/resources/js',
paths: {
'zepto' : 'libs/zepto',
'jquery' : 'libs/jquery',
'angular' : 'libs/angular',
'router' : 'libs/page',
'history' : 'libs/history.iegte8',
'event' : 'libs/eventemitter2'
},
shim: {
'zepto' : { exports: '$' },
'angular' : { exports : 'angular' },
'router' : { exports: 'page'},
'modernizr' : { exports: 'Modernizr' }
}
});
require([ 'jquery', 'angular', 'routes', 'modernizr', 'event' ], function($, angular, routes, Modernizr, Event) {
function bootstrap() {
var app = new Event(),
router = routes(app);
if (typeof console !== 'undefined') console.info('>> module routes loaded ... executing router');
router({ click: false, popstate: false });
if (typeof console !== 'undefined') console.info('>> executed router');
}
$(function() {
if (!Modernizr.history) {
require([ 'history' ], bootstrap);
require([ 'controllers/MainController' ], bootstrap);
} else {
require([ 'controllers/MainController' ], bootstrap);
bootstrap();
}
});
});
})(this.require);
mainApp.js
define(['angular'], function(angular) {
return angular.module('MyApp', []);
})
MainController.js
require(['mainApp'], function(mainApp) {
mainApp.controller('MainController', function($scope) {
$scope.data = {message: "Hello"};
})
});
test.html
<!DOCTYPE html>
<html ng-app="MyApp">
<head>
<script src="/assets/js/vendor/require.js" data-main="/assets/js/main"></script>
</head>
<body>
<div ng-controller="MainController">
{{ data.message + " world" }}
</div>
</body>
</html>
Any help appreciated.
The No module: MyApp problem is causes by the Angular automatic initialization: <html ng-app="MyApp">. Angular loads before mainApp.js, sees the ng-app and tries to find a module which is not (yet) there.
The solution is to manually bootstrap Angular from within main.js and inside the document load event, as described here.
I am not sure about the problem with Modernizr; I guess you are NOT loading it at all. RequireJs is not complaining because of the shim. How are you loading it? It is not included in your paths configuration. You may want to load Modernizr as independent script before all other scripts (as per recommendations), in which case no paths configuration is needed and the shim is enough.

Requirejs using shim

Using shim by requirejs2, there is a way to tell to requires that a module is already loaded?
Example:
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="undescrore.js"></script>
<script type="text/javascript" src="require.js'"></script>
<script type="text/javascript">
require.config({
paths: {
"backbone": '/vendor/js/backbone-min.js'
},
shim: {
'backbone': {
//These script dependencies should be loaded before loading
//backbone.js
deps: ['underscore', 'jquery'], // here I would like to load the already loaded library
}
}
});
</script>
Well, if underscore is already loaded and available, you do not need the shim at all. Backbone will happily load. If not, it's probably because underscore is not actually loaded.
It sounds however wrong to be only partially using require.js, you might as well AMD-load them all. To do that you will need to change your shim like this:
shim: {
backbone: {
deps: ["underscore", "jquery"],
exports: "Backbone"
},
underscore: {
exports: "_"
}
}
and of course update your paths.
I am not sure if you were able to find the best approach yet for your use case.
If you really - for some reason - need to add your other scripts without using RequireJS as in your code example #js999, then you would need to check if the global variable (jQuery, _) of those scripts exist and then define them as modules. From your code example it would look something like this:
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="undescrore.js"></script>
<script type="text/javascript" src="require.js'"></script>
<script type="text/javascript">
// check for jQuery
if (window.jQuery) {
define('jquery', [], function () {
return window.jQuery;
});
}
// check for underscore
if (window._) {
define('underscore', [], function () {
return window._;
});
}
require.config({
paths: {
// remove the file extension (.js)
"backbone": '/vendor/js/backbone-min'
},
shim: {
'backbone': {
deps: ['underscore', 'jquery']
}
}
});
</script>

Resources