$window.jQuery is undefined in a 3party module, but not window.jQuery - angularjs

In my webpack-es6-angularjs app I struggle with a problem where I could need some help: When trying to load a 3rd-party library, the 3rd-party library raises an error, that jQuery is undefined even though jQuery is exposed through webpack.
//webpack.config.js
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
})
The 3rd-party library uses jQuery through !$window.jQuery.support... but $window.jQuery does not exist – NOTE the extra $ from angularjs – where as window.jQuery exists as expected form the webpack config.
monkey-patching the 3rd-party library works but of course is to no solution. Any idea where this can come from and how this could be solved?

Okay, so I was able to solve it by explicitly injecting jQuery into the angularjs $window object:
import * as jquery from 'jquery';
import { IWindowService } from 'angular';
function jQueryService($window: IWindowService): any {
$window['jQuery'] = jQuery;
return jquery;
};
jQueryService.$inject = ['$window'];
export default jQueryService;

Related

How to add dependency in webpack?

If I use require to import a module the error is: webpack_require is not a function.
If I use the import statement then its function are not working and I get a type-error.
Does webpack not work with bower?
You could resolve dependency using an alias. Refer https://webpack.js.org/configuration/resolve/?_sm_au_=iVV0dsf3NTdNVrRc#resolvealias
In webpack add the following config:
resolve: {
alias: {
jQuery: path.resolve('./bower_components/jquery/dist/jquery.js'),
...
}
}
In the application wherever you need jQuery import using below line (assuming you are using CommonJS module):
var $ = require('jQuery');
Hope this helps :)

Unable to get react to work in requirejs environment

I have a regular ol' requirejs app, that pulls in modules in regular JS I write. I really want to start using reactjs but am not even able to get it to load with out throwing errors in the console.
My Paths
'react': '../node_modules/react/cjs/react.production.min', // there is a cjs and a umd (Universal Module Definition) version, I dont think I am UMD. we are Asynchronous Module Definition (AMD)
'reactDOM': '../node_modules/react-dom/cjs/react-dom.production.min',
'JSXTransformer': 'vendors/react/JSXTransformer-0.10.0',
'jsx': 'vendors/react/jsx',
Is it possible that there is a shim dependency that I need to setup?
'react' : {
'deps' : ['jquery']
},
'reactDOM' : {
'deps' : ['jquery']
}
I have also included them normally such as
require(["jquery", "jqueryUi", "bootstrap", "react", "reactDOM", "front", "owlCarousel", "select2", "blockui", ], function ($, jqueryUi, bootstrap, React, ReactDOM, front, owlCarousel, select2, blockui) {
$(document).ready(function(){
require([ $('#requirePageSpecificJs').val() ]); // this is set in php, result: "/require-mturk.js"
});
});
I get this error, when loading a page.
I am completely new to React, so I may be missing some things. Does the latest react require Babel to run, and if so do I need to include babel as a package, and add that as a shim? I am seeing some other posts of using requirejs with react but it is requiring different tools and stuff. completely lost here.

DefinitelyTyped: What does 'export = _;' means

I'm trying to use angular-material with a ng-metadata project and I run into some issues.
I use DefinitelyTyped for angular material and the first lines are:
declare module 'angular-material' {
var _: string;
export = _;
}
In my main.ts I try to import { ngMaterial } from 'angular-material';
then bootstrap( AppComponent, [ 'ngMaterial' ] ); but all I got is:
Error:(3, 10) TS2305: Module ''angular-material'' has no exported member 'ngMaterial'.
I don't know what I am doing wrong
When being used through ES6 or TypeScript, a common pattern that Angular modules follow is that they'll use their name as the default export. For example, one of the modules in my application looks like this:
const session = angular.module("smSession", [])
.service("session", SessionService)
.component("smLogin", Login)
.config(routes)
.run(loginRedirect);
export default session.name;
The reasoning behind this is that it makes the syntax for declaring an Angular module's dependencies cleaner; for example:
import angular from "angular";
import ngAnimate from "angular-animate";
import ngMaterial from "angular-material";
import uiRouter from "angular-ui-router";
let module = angular.module("myApp", [ ngAnimate, ngMaterial, uiRouter ]);
If they instead exported the entire module, you'd have to do this:
let module = angular.module("myApp", [ ngAnimate.name, ngMaterial.name, uiRouter.name ]);
So this is why the main module declaration for angular-material looks like it does - they're simply representing the fact that all you can import from the package is that one string representing the module's name. The rest of the type definitions are ambient - you can just use the angular.material namespace anywhere in your application without having to do an import.
EDIT: To clarify, here's the actual source of the file that gets imported when you import ngMaterial:
// Should already be required, here for clarity
require('angular');
// Load Angular and dependent libs
require('angular-animate');
require('angular-aria');
// Now load Angular Material
require('./angular-material');
// Export namespace
module.exports = 'ngMaterial';
Notice that require('./angular-material') doesn't return anything - that import effectively just runs the file that sets up the Angular module behind the scenes (effectively the same sort of code as in my examples). The only thing being exported from the module is the name.

Angular NgResource : Initialize error

i have a weird problem regarding angular resource. when i try to define it it causes the app to create an error. i dunno but is this the correct style of defining an angular Resource? tIA
main.js
'use strict';
require.config({
paths: {
jquery: 'libs/jquery/jquery-1.9.1',
angular: 'libs/angular/angular.min',
ngResource: 'libs/angular/angular-resource.min'
},
shim: {
angular: {
exports: 'angular'
},
resource : { deps : ['angular'], 'exports' : 'ngResource'},
}
});
require([
'jquery',
'angular',
//'ngResource',
'app',
'routes',
],
function ($, angular, app, routes) {// set main controller
$(function(){
var $html = $('html');
angular.bootstrap($html, [app['name']]);
$html.addClass('ng-app');
});
});
Just to help out those users who are not familiar with the code above; The code shows RequireJS configuration and initialization structure, and only a small part at the end is the actuall AngularJS code.
You have correctly configured RequireJS to include ngResource before initialization, but you didn't actually tell Angular to use it.
I'm not sure what app['name'] stands for, but your angular bootstrap call should include the ngResource module:
angular.bootstrap($html, ['ngResource']);
And, btw, I don't think you need to add the class ('ng-app') at the end.
In your callback when all resources are loaded, try to explicitly define the modules and dependancies before bootstrapping, like this:
angular.module('fooApp', ['ngResource']); // Module name and list of dependancies.
angular.bootstrap(document, 'fooApp');
There is no need to manually add the ng-app class, when this class is used to do bootraping automatically, witch is not what you want. You want to load the applicatiopns module when all scripts are loaded, with the ngResource module as a dependancy.
Hope this helps.

Where's the Backbone require.js dependency being resolved in this example?

In Addy Osmani's ToDo MVC example for require.js + Backbone: https://github.com/addyosmani/todomvc/blob/gh-pages/dependency-examples/backbone_require/js/main.js, he's using
Backbone.history.start() // line #31
without actually requiring Backbone. How/why does this work? Is the shim enabling this? Or am I missing something obvious?
If you have a look in the code, view/app.js is actually requiring Backbone.
And the backbone shim is exporting the global Backbone variable.
If no other modules will actually require the shim, it won't be loaded, so it won't be accessible.
You can try to remove the 'views/app' requirements in main.js to see for yourself.
As #ChristiMihai mentioned, Backbone created a global Backbone object, correct. Let me give you an example of what I do in my Require.js / Backbone / Handlebars app:
First, I include Require config in <head>:
var require_config = {
baseUrl: "/javascripts",
waitSeconds: 5,
paths: {
'cdnjs': 'http://ajax.cdnjs.com/ajax/libs',
'aspnetcdn': 'http://ajax.aspnetcdn.com/ajax',
'cloudflare': 'http://cdnjs.cloudflare.com/ajax/libs',
'local': '/javascripts'
}
}
if (typeof require !== 'undefined') {
require.config(require_config);
} else {
var require = require_config;
}
After that I bootstrap a require module, e.g:
define([
'app'
],
function() {
console.log('Homepage module');
/*
... this is the meat of your app...
you can add other dependencies beside `app` too
*/
});
Now app is the main dependency which resolves via baseUrl to /javascripts/app.js and includes all necessary deps in order, and looks like this:
define([
'order!cdnjs/json2/20110223/json2',
'order!cloudflare/underscore.js/1.3.1/underscore-min',
'order!cloudflare/backbone.js/0.9.2/backbone-min',
'order!handlebars/handlebars-1.0.0.beta.6.min',
'order!lib/ns',
'bootstrap'
], function(){});

Resources