Auth0 with Angular 1.5.8 and webpack - javascript

I'm trying to integrate Auth0 into my Angular project that I'm bundling with webpack. When I launch the app I get the error:
Error: [$injector:modulerr] Failed to instantiate module auth0.lock due to:
Error: Auth0Lock must be loaded.
My Config.js looks like:
import 'auth0-lock';
import 'angular-lock';
import 'angular-jwt';
import angular from 'angular';
import uiRouter from 'angular-ui-router';
import loginController from 'components/login/login.controller';
import authService from 'shared/auth/auth.service';
const app = angular.module('app',[uiRouter, 'auth0.lock', 'angular-jwt']);
app.config(($stateProvider, lockProvider, $urlRouterProvider, $locationProvider) => {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('login',{
url:'/login',
template: require('components/login/login.view.html'),
controller: loginController,
controllerAs: 'vm'
})
lockProvider.init({
clientID: 'xxx',
domain: 'xxx'
});
$locationProvider.html5Mode(true);
});
app.service('authService',authService);
export default app;
And my index.js is
import angular from 'angular';
import appModule from './config';
angular.bootstrap(document, [appModule.name]);
run.$inject = ['$rootScope', 'authService', 'lock'];
function run($rootScope, authService, lock) {
// Put the authService on $rootScope so its methods
// can be accessed from the nav bar
$rootScope.authService = authService;
// Register the authentication listener that is
// set up in auth.service.js
authService.registerAuthenticationListener();
// Register the synchronous hash parser
lock.interceptHash();
console.log('success');
}
I've read on a few places that setting window.Auth0Lock in the webpack config would fix it, but still no luck.
new webpack.ProvidePlugin({
"window.Auth0Lock" : "auth0-lock"
}),
My problem is exactly the same as this question, but alas it remains unanswered. I would appricate any help.
Edit: The below solution doesn't seem to solve my problem and I'm still stuck. I believe I'm requiring all the required dependencies.

So I do need lock.min.js, and when I tried to require it in my config file webpack would throw up. I also tried downloading and requiring the distributable, but that also was giving me problems. I gave up and now I'm referencing the CDN directly on my index.html. I think you can use webpack script-loader as well.
<script type="text/javascript" src="https://cdn.auth0.com/js/lock/10.5/lock.min.js"></script>
<script src="bundle.js"></script>
Hope this helps.

Related

Angular 6 hybrid app does not load AngularJS components

I aim to upgrade a large AngularJS version 1.7.3 to a hybrid app using Angular 6. I finished the preparation phase where I had to convert all my controllers/directives into an AngularJS component. I have created a new Angular 6 project skeleton with the command line:
ng new hybrid-app
I copy-pasted the AngularJS legacy code inside the Angular 6 app in src/ng1 folder.
This is how my app.module.ts look like in order to bootstrap the AngularJS 1.x app from Angular 6:
import {BrowserModule} from '#angular/platform-browser';
import {NgModule} from '#angular/core';
import {UpgradeModule} from '#angular/upgrade/static';
import {AppComponent} from './app.component';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
UpgradeModule
],
providers: [],
// bootstrap: [AppComponent] // No Bootstrap-Component
})
export class AppModule {
constructor(private upgrade: UpgradeModule) {
}
ngDoBootstrap() {
this.upgrade.bootstrap(document.body, ['myAngularJsModule'], {strictDi:
true});
}
}
When I do ng serve, there is no error and I can see the Angular 6 app redirecting to the default AngularJS routing which is /login. This is my AngularJS route file:
angular.module('myAngularJsModule').config(["$locationProvider", function ($locationProvider) {
$locationProvider.html5Mode(false);
}])
.config(
['$stateProvider', '$urlRouterProvider', '$locationProvider',
function ($stateProvider, $urlRouterProvider) {
/**
* Default route.
*/
$urlRouterProvider.otherwise('/login');
$stateProvider
.state('login', {
url: '/login',
params: {message: null},
component: 'loginComponent',
template: '<login-component></login-component>'
});
As you can see I have a default route to /login and the Angular 6 app knows how to get there. The issue that I have now is:
There is no error in the console but I have a blank page, it seems like component from AngularJS is not loaded properly and therefore does not show anything on the browser. I tried to replace the template by a simple:
template: '<h1>Hello World!<h1>'
And it will show up properly. Anyone knows why my AngularJS component is not loaded by Angular 6, is it something to do with the UIRouter?
The error that I have now is:
Error: StaticInjectorError(AppModule)[UpgradeModule -> Injector]:
StaticInjectorError(Platform: core)[UpgradeModule -> Injector]:
NullInjectorError: No provider for Injector!
at NullInjector.push../node_modules/#angular/core/fesm5/core.js.NullInjector.get (core.js:1062)
at resolveToken (core.js:1300)
at tryResolveToken (core.js:1244)
at StaticInjector.push../node_modules/#angular/core/fesm5/core.js.StaticInjector.get (core.js:1141)
at resolveToken (core.js:1300)
at tryResolveToken (core.js:1244)
at StaticInjector.push../node_modules/#angular/core/fesm5/core.js.StaticInjector.get (core.js:1141)
at resolveNgModuleDep (core.js:8376)
at _createClass (core.js:8423)
at _createProviderInstance (core.js:8393)
I may need to have a look at this: https://github.com/ui-router/angular-hybrid
I will delete my old angular-ui-router and replace it by this one.

AnguarJS with ES2016 load config module

I'm trying to start a new Angular 1 Application based on ES6. I use webpack and the babel-loader to convert the JS.
My problem now is to load an own config module. Please have a look at this:
// config/config.js
import angular from 'angular';
export default angular.module('config')
.factory('config', () => {
return {
url: {
products: 'https://....'
},
products: []
}
})
The corresponding app.js reads (I stripped some imports):
import angular from 'angular';
import config from './config/config';
import HomeCtrl from './controller/HomeController';
let app = () => {
return {
template: require('./app.html')
}
};
const MODULE_NAME = 'app';
angular.module(MODULE_NAME, [uiRouter, config])
.directive('myapp', app)
.config(['$stateProvider', '$urlRouterProvider', 'config', function ($stateProvider, $urlRouterProvider, config) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state("home", {
"url": "/",
"template": require('./views/home.html'),
"controller": HomeCtrl,
'controllerAs': 'app'
})
}]);
export default MODULE_NAME;
The error message says:
Uncaught Error: [$injector:nomod] Module 'config' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
What did I missed here? Is there a better way to load an application wide config object to use in certain services?
Thanks for help!
When you create a module, you have to call module() with two args: the name and the dependencies. If you call it with only one parameter, you get the existing module with that name.
Change your module config declaration to:
export default angular.module('config', [])
.factory('config', () => {
return {
url: {
products: 'https://....'
},
products: []
}
}).name
In addition, I always export only the .name of a new module. When you import the module, you just need its name.
Hope it helps.
When you declare your dependent modules in your main module definition you need to use the string identifier, not the actual angular.module (at least here it's specified as Array[String]: https://docs.angularjs.org/api/ng/function/angular.module
So, you should change to this:
angular.module(MODULE_NAME, ['config'])
Please check Angular documentation - module dependencies it's array of strings, but not dependent modules types or instances
angular.module(name, [requires], [configFn]);
when
requires (optional) Array<string>
So your solution to use next declaration
angular.module(MODULE_NAME, ['config'])
https://docs.angularjs.org/api/ng/function/angular.module

Lazy loading Angular modules with Webpack

I'm trying to get lazy-loaded Angular modules working with Webpack, but I'm having some difficulties. Webpack appears to generate the split point correctly, because I see a 1.bundle.js getting created that contains the code for the child app, but I don't see any request for 1.bundle.js when I load the page, and the child app doesn't initialize. The console.log never seems to fire, and it doesn't even appear to get to the point where $oclazyload would initialize the module.
There are a few points where I am confused.
1) Will webpack make the request to the server, or do I have to load the second bundle manually? (I've tried both, and neither works)
2) If I do need to load the bundles manually, in what order should they be loaded?
3) The third argument to require.ensure supposedly lets you control the name of the bundle, but the bundle is named 1.bundle.js no matter what string I pass.
4) Why can't I step through the code inside the require.ensure block in the debugger? When I do so I end up looking at this in the Chrome source view:
undefined
/** WEBPACK FOOTER **
**
**/
(Code Below)
Main entry point code:
'use strict';
import angular from 'angular';
import 'angular-ui-router';
import 'oclazyload';
angular.module('parentApp', [
'ui.router',
])
.config(['$urlRouterProvider', '$locationProvider', ($urlRouterProvider, $locationProvider) => {
$urlRouterProvider
.otherwise('/');
$locationProvider.html5Mode(true);
}])
.config(['$stateProvider', ($stateProvider) => {
$stateProvider
.state('child-app', {
url: '/child-app',
template: '<child-app></child-app>',
resolve: {
loadAppModule: ($q, $ocLazyLoad) => {
return $q((resolve) => {
require.ensure(['./child-app/app.js'], (require) => {
let module = require('./child-app/app.js');
console.log(module);
$oclazyload.load({name: 'childApp'});
resolve(module.controller);
});
})
}
},
controller: function() {
}
})
}]);
Child app:
'use strict';
import childAppTemplateURL from '../templates/child-app.html';
import childAppController from './controllers/childAppController';
export default angular.module('parentApp.childApp', [])
.component('applicationListApp', {
templateUrl: childAppTemplateURL,
controller: childAppController
});
The problem was unrelated to the require.ensure implementation. It was caused by some weirdness in the way ocLazyLoad is packaged (https://github.com/ocombe/ocLazyLoad/issues/179). The fix in my case was simple, I just added 'oc.lazyLoad' to the module dependencies.
angular.module('parentApp', [
'ui.router',
'oc.lazyLoad'
])
To answer two of my own questions, Webpack does indeed make a request to the server for the bundle, and you do not have to manually load the bundle. One gotcha that really confused me: the resolve block will fail silently if it contains a promise that won't resolve. In my case $ocLazyLoad.load() was failing, but there was no indication of the failure. The only clue was that the state provider wasn't adding the <child-app></child-app> markup to the DOM, which meant that it was actually initializing the state.

ES6 import syntax with Angular 1.5 UI Router

I'm trying to combine Angular 1.5, UI Router using ES6 import modules syntax with Babel & Webpack.
In my app.js I have:
'use strict';
import angular from 'angular';
import uiRouter from 'angular-ui-router';
...
import LoginCtrl from './login/login.ctrl.js'
const app = angular.module("app", [
uiRouter,
...
])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('login', {
url: '/login',
templateUrl: '...',
controller: LoginCtrl,
controllerAs: 'login'
})
});
In login/login.ctrl.js I have:
'use strict';
export default app.controller("LoginCtrl", function() {
//code here
});
When I started my app I have following error message:
ReferenceError: app is not defined
bundle.js:35422:2
Error: [$injector:modulerr] Failed to instantiate module app due to:
[$injector:nomod] Module 'app' is not available! You either misspelled the module name or forgot to load it.
And second question. How can I use controller: "loginCtrl as login" syntax with ES6 import/export?
You are referring to 'app' variable inside your 'login/login.ctrl.js' but the variable is not defined (because you are importing the controller before defining it).
EDIT: Anyway each module has its own scope so you can't refer to variable from different module this way.
The solution I have in my mind is following:
Inside 'login/login.ctrl.js' create new module
'use strict';
import angular from 'angular';
angular.module('ctrlsModule', [])
.controller('LoginCtrl', function () {
});
Add the module as dependence of your main 'app' module
'use strict';
import angular from 'angular';
import uiRouter from 'angular-ui-router';
...
import './login/login.ctrl.js';
angular.module('app', [uiRouter, 'ctrlsModule', ...])
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('login', {
url: '/login',
templateUrl: '...',
controller: 'LoginCtrl',
controllerAs: 'login'
});
});
I haven't tested the code but I believe you can see what I mean. Not sure what you mean with the second question but controllerAs in ES6 should work the same way as in ES5.

Injecting Angular modules: Unknown provider

I followed a tutorial on how to organize and Angular project. I have a ng directory that contains all my controllers, services and my routes.js. This is then bundled all together into an app.js by my gulp config.
My module.js is like this:
var app = angular.module('app', [
'ngRoute',
'ui.bootstrap'
]);
Here's a bit of my routes.js:
angular.module('app')
.config(function ($routeProvider) {
.when('/login', { controller: 'LoginCtrl', templateUrl: 'login.html'})
});
Here's what my working LoginCtrl looks like:
angular.module('app')
.controller('LoginCtrl', function($scope, UserSvc) {
$scope.login = function(username, password) {
...
}
})
The tutorial didn't make use of any Angular modules and I wanted to try one out. I added ui.bootstrap to my page from a CDN and try to change the LoginCtrl to:
angular.module('app')
.controller('LoginCtrl', function($scope, $uibModal, UserSvc) {
...
})
But this throws me the following error:
"Error: [$injector:unpr] Unknown provider: $templateRequestProvider <- $templateRequest <- $uibModal
What is causing this error? In every tutorial I find this seems to be how they load a module, the only difference I see is that the tutorial don't seem to be using a router.
PS: Note that if I use an empty module list [] I get the exact same error. If I use a non-existing module ['helloworld'] I get an errorModule 'helloworld' is not available'. So I'm concluding that my `ui.bootstrap' module is indeed available.
EDIT: Plunker fiddle here: http://plnkr.co/edit/FWHQ5ZDAByOWsL9YeMUH?p=preview
angular route is another module you should not only include but also use like this
in the app module creation
means DI of route
angular.module('app', ['ngRoute']);
Please go through the angular route doc
Remove ['ui.bootstrap'] form controller. You should add dependencies only one time but you add it twice so the second dependency list override the first one.
angular.module('app')
.controller('LoginCtrl', function($scope, UserSvc) {
... })
your routes snippet looks wrong, you should be hanging the when call off $routeProvider and maybe declare $routeProvider as an injected val if it's not being picked up e.g.
angular.module('app')
.config(["$routeProvider", function ($routeProvider) {
$routeProvider.when('/login', { controller: 'LoginCtrl', templateUrl: 'login.html'})
}]);
I have checked your link. I think there is a serious issue with angular and ui bootstrap version.In ui-boostrap dashboard, it is written that 0.12.0 is the last version that supports AngularJS 1.2.x. I have tried with all combinations but it doesn't work with your angular version.
I suggest you to change angular version to latest and ui-bootstrap version to latest so it will work.
Please check out this working Plukr
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js'></script>
<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular-route.js'></script> //change this to latest also.
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.0.3/ui-bootstrap.min.js'></script>
<script src='./app.js'></script>
If you want to go with your angular version only. I'd request you to do some R&D. Try with different versions of ui-bootstrap. still if it doesn't work you can make PR.

Categories