ng2-datetime: jQuery is not defined - javascript

I've installed the jQuery typings and all the project dependencies. But I really can't wrap my head around this one.
template source (jade):
.form-group
.col-sm-4
label Birth Date
datetime(name="birthDate", [(ngModel)]="transaction.general_information.birthDate")
...
module source (ts):
import { NKDatetimeModule } from 'ng2-datetime/ng2-datetime';
...
#NgModule({
imports: [
...,
NKDatetimeModule
],...
})
...
Error (Dev Console Chrome):
EXCEPTION: Error in ./OrdersNewStep1 class OrdersNewStep1 - inline template:0:1046 caused by: jQuery is not defined
Github project:
ng2-datetime
Using:
Angular2
Webpack

WebPack is placing all modules into an isolated scopes. Meanwhile, most of plugins expect jQuery to be defined in a global scope. You can fix it using Provide plugin for webpack like this
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery"
})

Related

Webpack error on lodash load using externals config

i am trying to modify a current project using webpack. On my scripts i am using lodash library but i have also scripts that are not written on ES6 so i load lodash globally using a normal script tag.
Based on the webpack documentation i have added the below config on the webpack (https://webpack.js.org/configuration/externals/).
lodash : {
commonjs: 'lodash',
amd: 'lodash',
root: '_' // indicates global variable
},
I compile the code using babel without any problem but when the actual code is executed i receive the below error
"TypeError: Cannot read property 'forEach' of undefined"
If i remove the import _ from "lodash"; statement from the file then the issue is resolved and script is working as expected as _ is on global.
But this was expected to work also without adding the externals correct ? According with the webpack example for jquery
module.exports = {
//...
externals: {
jquery: 'jQuery'
}
};
The below code will be unchanged
import $ from 'jquery';
$('.my-element').animate(/* ... */);
In my case why is not working ? Any suggestions ? ideas?
I think i found a solution, after i read the documentation again and again i noticed that message which is also on yellow border
An object with { root, amd, commonjs, ... } is only allowed for libraryTarget: 'umd'. It's not allowed for other library targets.
So i have changed my config from
lodash : {
commonjs: 'lodash',
amd: 'lodash',
root: '_' // indicates global variable
}
to
lodash: '_'
and issue solved, now is working as expected. It will be great of course if i understand why this was an issue

jQuery not available as "$" when using webpack's ProvidePlugin

I am attempting to use jQuery as $ in my webpack application's entry index.js file, and I am receiving this error when running my application in the browser:
Uncaught TypeError: Cannot read property 'fn' of undefined
This is due to a line in a module I am importing called bootstrap-switch, and the line in question is:
$.fn.bootstrapSwitch = function() {
So I do not have $ working as a global variable. I followed instructions on the ProvidePlugin docs, as shown below. I also tried the answer provided in this question but that didn't work.
This is an abbreviated version of my webpack.config.js file:
module.exports = {
entry: {
main: './src/index.js'
},
plugins: {
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
}
}
And this is my src/index.js file:
import 'bootstrap-switch';
console.log('I am running');
Any help would be much appreciated.
EDIT
A previous version of this question asked about a build error that was actually an ESLint error. Thank you to #UjinT34 for helping me resolve that problem and focus on the actual error outlined above.
I'm adding this as an answer for future users to find.
Try adding 'window.jQuery': 'jquery' to your webpack.ProvidePlugin() settings.
module.exports = {
...
plugins: [
new webpack.ProvidePlugin( {
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
} )
]
};
no-undef is a ESlint error. It doesn't know about your webpack setup. You can specify global variables in esling config:
{
"globals": {
"$": "readonly",
"jQuery": "readonly"
}
}

Bootstrap 4 Beta importing Popper.js with Webpack 3.x throws Popper is not a constructor

So Bootstrap 4 Beta is out... yey! However Tether has been replaced by Popper.js for tooltip (and other features). I saw an error thrown in the console fast enough to advise me of the change to Popper.js:
Bootstrap dropdown require Popper.js
Seems easy enough, I went and updated my webpack.config.js (the entire config can be seen here) and Bootstrap then started working (the only change I did was to replace Tether with Popper):
plugins: [
new ProvidePlugin({
'Promise': 'bluebird',
'$': 'jquery',
'jQuery': 'jquery',
'window.jQuery': 'jquery',
'window.$': 'jquery',
Popper: 'popper.js'
}),
I also did the import 'bootstrap' in my main.ts file.
However I now have another problem (which I did not have with Tether), a new error is thrown in the console:
Uncaught TypeError: Popper is not a constructor
If I try to debug in Chrome, I do have Popper loaded as an Object (which is why Bootstrap stopped complaining) as you can see in the print screen below.
Finally to include all my code. I use Bootstrap tooltip with a simple custom element built with Aurelia and TypeScript (which used to work with previous Bootstrap alpha 6 and Tether)
import {inject, customAttribute} from 'aurelia-framework';
import * as $ from 'jquery';
#customAttribute('bootstrap-tooltip')
#inject(Element)
export class BootstrapTooltip {
element: HTMLElement;
constructor(element: HTMLElement) {
this.element = element;
}
bind() {
$(this.element).tooltip();
}
unbind() {
$(this.element).tooltip('dispose');
}
}
Looks like I did not import Popper correctly, if so then what is the best way to achieve that with Webpack 3.x?
While browsing Bootstrap 4 documentation. I actually found a section about Webpack which explains how to install it correctly. Following the Bootstrap - installing with Webpack documentation, the answer is to simply modify the webpack.config.js with the following:
plugins: [
// ...
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
Popper: ['popper.js', 'default']
})
// ...
]
and let's not forget to import it in the main.ts
import 'bootstrap';
and voilĂ ! We are back in business :)
If you are using Webpack Do this:
window.$ = window.jQuery = require('jquery');
window.Popper = require('popper.js').default; // pay attention to "default"
require('bootstrap/dist/js/bootstrap');
In bootstrap": "^4.1.1" no need to import jquery and popper.js because those plugins will be already included when 'bootstrap' or bootstrap's plugins imported individually.
Notice that if you chose to import plugins individually, you must also
install exports-loader
No need to require files require('exports-loader?file ... '); as mentioned here because this will be taken care automatically by just installing $ npm install exports-loader --save-dev
import 'bootstrap'; // Import all plugins at once
//
// Or, import plugins individually
//
// import 'bootstrap/js/src/alert';
// import 'bootstrap/js/src/button';
// import 'bootstrap/js/src/carousel';
// import 'bootstrap/js/src/collapse';
// import 'bootstrap/js/src/dropdown';
// import 'bootstrap/js/src/modal';
// import 'bootstrap/js/src/popover';
// import 'bootstrap/js/src/scrollspy';
// import 'bootstrap/js/src/tab';
// import 'bootstrap/js/src/tooltip';
// import 'bootstrap/js/src/util';
There is no need to do anything like below:
const webpack = require('webpack');
module.exports = {
configureWebpack: {
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
Popper: ['popper.js', 'default']
})
]
}
}
I am a vue.js developer and in new vue-cli-3, we create vue.config.js in root and place code like above to register new plugin, but as said there is no need to do all this in bootstrap": "^4.1.1".
Bootstrap's tooltip plugin is depend on popper.js and need to be enabled manually, so you can do like below in the component where you use tooltip element:
<script>
import $ from 'jquery';
export default {
mounted() {
$('[data-toggle="tooltip"]').tooltip();
},
};
</script>
I just ran into the same issue, and the solution is described here: https://github.com/FezVrasta/popper.js/issues/287
My main.ts now looks like something like the following:
import "jquery";
import Popper from "popper.js";
(<any>window).Popper = Popper;
require("bootstrap");
And I had to run npm install #types/requirejs --save to get the call to require working.
EDIT: I totally missed this the first time around, but the documention actually has a better way to solve this https://getbootstrap.com/docs/4.0/getting-started/webpack/
plugins: [
...
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
Popper: ['popper.js', 'default'],
// In case you imported plugins individually, you must also require them here:
Util: "exports-loader?Util!bootstrap/js/dist/util",
Dropdown: "exports-loader?Dropdown!bootstrap/js/dist/dropdown",
...
})
...
]
In ASP.net Core 2 project add the following scripts to of main HTML file ("_Layout.cshtml" file)
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/js/popper.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.min.js"></script>
For me it's working.

How to call bootstrap's jQuery plugins in ES6

I'm stuck trying to call the bootstrap's jQuery plugins, like popover, tooltip, modals, ...
I'm using webpack and this is my ES6 javascript:
import $ from 'jquery';
//import Bootstrap from 'bootstrap-sass';
//import Bootstrap from 'bootstrap-loader';
import Bootstrap from '../vendor/bootstrap.min.js';
class Test {
constructor () {
$('[data-toggle="tooltip"]').tooltip({ html: true });
}
}
I've tried to install bootstrap with npm, but after that i wasn't sure which one node-modules i had to import (like you can see in commented lines in the imports). So, i thought to import directly the bootstrap.min.js.
The fact is that i still have an error (independently if i try with popover/modals/tooltip) like this in my app.js that is my javascript generated from the webpack:
Uncaught TypeError: (0 , _jquery2.default)(...).tooltip is not a function
Like i say, i'm stuck here.
Last thing, the boostrap CSS works correctly thanks to this:
gulp.task('bootstrap-fonts', function() {
return gulp.src('node_modules/bootstrap-sass/assets/fonts/bootstrap/*')
.pipe(gulp.dest('./app/assets/fonts/bootstrap'));
});
gulp.task('dev', ['css', 'bootstrap-fonts', 'browser-sync', 'webpack'], function () {
gulp.watch('src/scss/**/*.scss', ['css']);
gulp.watch('src/js/**/*.js', ['webpack']);
gulp.watch('app/*.html', ['bs-reload']);
});
Because the bootstrap library depends on jQuery,
you should try to add the following plugin to the 'plugins' array in your webpack.config.js so that the bootstrap module will use the jQuery global object:
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": 'jquery'
}),
This plugin will actually injects the 'jquery' module in any other module that ask for him (means, every module that use the objects jQuery or $ or window.jQuery), and bootstrap is one of them.

How to use Webpack ProvidePlugin to load Backbone-relational right?

I have defined webpack ProvidePlugin to load Backbone-relational library as follows.
plugins: [
new webpack.ProvidePlugin({
$ : "jquery",
Backbone : "backbone",
_ : "underscore",
"Backbone.Relational": "backbone-relational",
})
However Backbone-relational also exports:
Backbone.RelationalModel
Backbone.HasOne
Backbone.HasMany
etc...
My problem is that I can not have them all exported. What is the right way to do this with webpack?
Try to use relational shim as described here

Categories

Resources