Angular with imports - adding resource to controller - angularjs

I'm trying to import a resource to a contoller with es6 imports.
I've got this resource:
import angular from 'angular';
import ngresource from 'angular-resource';
personsResource.$inject = ['$resource'];
function personsResource ($resource) {
// return $resource ...
}
export default angular.module('resources.persons', [ngresource])
.service('personsResource', personsResource)
.name
When in my module index.js I inject it like this:
//other imports
import personsResource from '../../resources/persons.resource';
//console.log(personsResource) returns resources.persons
export default angular.module('app.home', [personsResource])
.config(routing)
.controller('HomeController', HomeController)
.name
And my HomeController looks like this:
HomeController.$inject = [personsResource];
export default function HomeController(personsResource) {
}
And here personsResource is undefined. As I understand, I don't need to import it again in HomeController since I imported it in index.js and passed to HomeController from there.
I actually tried to import it again in HomeController but that didn't help either. Any ideas what I'm doing wrong?

Related

AngularJS modules + Webpack + ES6 imports - Problem with dependency injection & concat order

Problem Summary
I am migrating an old AngularJS application to use Webpack and I am splitting it into three parts, which I want to represent as AngularJS modules:
src-ts-admin
src-ts-common
src-ts-store
For example I'd like 'src-ts-admin' to consume services from 'src-ts-common', but unfortunately webpack bundles files in the wrong order for AngularJS Dependency Injection, so that I end up with errors like ..
Error: "[$injector:unpr] Unknown provider: filterServiceProvider <- filterService <- initializerService
.. where initializerService is a service from src-ts-admin and filterService is from src-ts-common. The core of the problem is that
module("ADMIN").service("initializerService") executes before
module("COMMON).service("filterService")
.. although I cannot spot the problem in the dependencies.
File Overview
src-ts-admin: app.ts
This is the webpack entry point, however not so interesting. The application routing will trigger app.initializer.ts.
import angular from 'angular';
import { appModule } from './app.module';
src-ts-admin: app.module.ts
import angular from 'angular';
import commonModuleName from '../src-ts-common/common.module';
var modulezz;
modulezz = [commonModuleName,'ngRoute', 'ui.router', 'ui.multiselect', 'ui.bootstrap', 'ui.bootstrap-slider', 'ui.bootstrap.buttons', 'duScroll',
'ngMessages', 'colorpicker.module', 'angular-bind-html-compile', 'pascalprecht.translate'];
export var appModule = angular.module("ADMIN", modulezz);
export default appModule.name;
src-ts-admin: app.initializer.ts
import angular from "angular";
import appModuleName from "./app.module";
import { filterService } from "../src-ts-common/service/filter-service-model";
export class InitializerController {
static $inject = ...etc...
constructor(...etc...) {
/* THIS IS KICKED OFF BY AN ANGULAR ROUTE, THIS KICKS OFF THE InitializerController BELOW */
}
}
angular.module(appModuleName).controller("initializerController", InitializerController);
export class InitializerService {
static $inject = ["$stateParams", "$window", "$timeout", "filterService", ...etc...];
constructor(private $stateParams, private $window, private $timeout, private filterService: filterService, ...etc...) {
/* THIS IS WHERE THE DEPENDENCY INJECTION FAILS */
}
}
angular.module(appModuleName).service("initializerService", InitializerService);
src-ts-common: common.module.ts
import angular from 'angular';
export default angular.module("COMMON",[]).name;
src-ts-common: filter.service.ts
import angular from "angular";
import commonModuleName from '../common.module';
export class filterService {
static $inject = [];
constructor() {
/* ...simplified... */
}
}
angular.module(commonModuleName).service("filterService", filterService);
My thoughts
The error I get is ..
Error: "[$injector:unpr] Unknown provider: filterServiceProvider <- filterService <- initializerService
.. which indicates to me that app.initializer.ts is executed before filter.service.ts, although it is importing that file.
Do you see any obious errors I made? Do you have any best practices to structure AngularJS + Webpack module imports and cut files?
--- Solution (Update!) ---
Thanks to https://stackoverflow.com/a/59631154/5244937 I could solve my problem. The pattern I should have used was to initialize the angular modules (e.g. angular.module(commonModuleName).service("filterService", filterService);) in the app.module.ts and common.module.ts files and NOT together with their class implementations.
Here the corrected files:
src-ts-admin: app.ts
/* here i am more or less just kicking off the angular application after i import app.module.ts */
import { appModule } from './app.module';
appModule.run(["$rootScope", "$location", ...,
function ($rootScope, $location, ...) {
..
}
appModule.controller('appController', ['$scope', ..,
function ($scope: any, ...) {
..
}
src-ts-admin: app.module.ts
/** here (1) i am initializing all angular controllers, services, factories from the ADMIN package & (2) importing the COMMON module */
import angular from 'angular';
import ngRoute from 'angular-route';
import uiRouter from 'angular-ui-router';
import 'angular-messages';
import 'angular-translate';
import dptCommonModuleName from '../src-ts-common/common.module';
var modulezz;
modulezz = [dptCommonModuleName, ngRoute, uiRouter, 'ui.multiselect', 'ui.bootstrap', 'ui.bootstrap-slider', 'ui.bootstrap.buttons', 'duScroll',
'ngMessages', 'colorpicker.module', 'angular-bind-html-compile', 'pascalprecht.translate'];
export var appModule = angular.module("DPT", modulezz);
export var appModuleName = appModule.name;
/**
* Services
*/
angular.module(appModuleName).service("systemParameterService", systemParameterService);
angular.module(appModuleName).service("statisticsService", statisticsService);
angular.module(appModuleName).service("deletionCheckService", deletionCheckService);
...
src-ts-admin: app.initializer.ts
/** here i have removed (1) the import of angular.module.ts and (2) the initialization of angular controller and service "initializerController" and "initializationService" */
import angular from "angular";
import { filterService } from "../src-ts-common/service/filter-service-model";
export class InitializerController {
static $inject = ...etc...
constructor(...etc...) {
/* THIS IS KICKED OFF BY AN ANGULAR ROUTE, THIS KICKS OFF THE InitializerController BELOW */
}
}
export class InitializerService {
static $inject = ["$stateParams", "$window", "$timeout", "filterService", ...etc...];
constructor(private $stateParams, private $window, private $timeout, private filterService: filterService, ...etc...) {
/* THIS IS WHERE THE DEPENDENCY INJECTION FAILS */
}
}
src-ts-common: common.module.ts
/* here i have added the initialization of the angular service filterService and all other services, factories, .. contained in that module */
var moduleName = angular.module("DPT.COMMON",[]).name
export default moduleName;
angular.module(moduleName).factory("filterModel", function () { return filterModel; });
angular.module(moduleName).factory("filterPresetModel", function () {return filterPresetModel;});
angular.module(moduleName).factory("productModel", function () {return productModel;});
angular.module(moduleName).factory("propertyProfileModel", [function () {return propertyProfileModel;}]);
angular.module(moduleName).factory("propertyValueModel",function () {return propertyValueModel;});
src-ts-common: filter.service.ts
/** here i have (1) removed the import of common.module and (2) teh initialization of angular.module(..).service("filterService", ..) */
import angular from "angular";
export class filterService {
static $inject = [];
constructor() {
/* ...simplified... */
}
}
Your dependencies are inverted, Module should import its deps (other modules or filters / services / components).
If you will follow this, your AppModule will import its child modules, which in it turn will import its services.
That means that your services should only export the class.
The relevant Module should import the service class, and register it on the module & export the Module name.
The parent Module should import its child Modules.
// serviceX.js
export class serviceX {
static $inject=[];
...
}
// childModule.js
import {serviceX} from './services/serviceX.js';
import {componentY} from './components/componentY.js';
import angular from 'angular';
export default angular.module('childModule', [])
.service('serviceX', serviceX)
.component('componentY', componentY)
// ... rest of the childModule deps
.name;
// appModule.js
import {externalDep} from 'external-dep';
import childModule from './modules/childModule';
import angular from 'angular';
const appModule = anguler.module('appModule', [externalDep, childModule]).name;
angular.bootstrap(document, [appModule]);

ES6 Angular 1.6 LokiJS module injection filename error

My probleme is :
Uncaught Error: [$injector:modulerr] Failed to instantiate module app due to:
Error: [$injector:modulerr] Failed to instantiate module function Loki(filename, options) due to:
Error: [$injector:unpr] Unknown provider: filename
I use Agular 1.6 withe lokiJs for angular.
The code is formated in ES6 with webpack.
notice I commented all references to Loki in my controller.
Only injection is used in.
export default class loginController{
constructor($scope, Loki, $mdDialog, $timeout, $location, $cookies){
console.log('foo');
if($cookies.get('user')){
$location.path('/programmes');
}
this.user = {
login:'plop',
pwd:undefined
}
var db_name = 'app.db';
//var db = new Loki('${db_name}');
var profiles;
/*
db.loadDatabase({},function(){
return profiles = db.getCollection('profiles') || db.addCollection('profiles');
});
*/
console.log('ttoot');
this.ui = {
'shake' :false,
'register': false,
};
}
for the controller and my app.js :
import angular from 'angular';
import ngMaterial from 'angular-material';
import ngAnimate from 'angular-animate';
import ngMessage from 'angular-messages';
import ngRoute from 'angular-route';
import ngCookies from 'angular-cookies';
import lokijs from 'lokijs';
/*import './../dependencies/loki/lokijs.js';
import loki from './../dependencies/loki/loki-angular.js';
*/
import uirouter from 'angular-ui-router';
import appLogin from './components/login/login.module.js';
import appProg from './components/programmes/prog.module.js';
import appSeance from './components/seances/seances.module.js';
import router from './configs/routing.js';
import run from './run/run.js';
angular.module('app', [
ngMaterial,
ngAnimate,
ngMessage,
ngRoute,
ngCookies,
appLogin,
appProg,
appSeance,
lokijs,
uirouter,
])
.config(router)
.run(run)
;
thanks for your help !

Angular controller is not registering during unit testing

I'm attempting an Angular app with a Grails backend, and I'm unit testing the controller, simply to see if it exist, before I start working with it. Unfortunately, it is giving me the following error:
[$controller:ctrlreg] The controller with the name 'SecurityController' is not registered.
Here's my unit testing code:
import angular from 'angular';
import 'angular-mocks';
import worldManagerApp from '../../src/world-manager-app';
import security from '../../src/security/security';
const {inject, module} = angular.mock;
describe('SecurityController', () => {
let $state;
let vm;
beforeEach(module(worldManagerApp));
beforeEach(module(security));
beforeEach(inject((_$state_, $controller) => {
$state = _$state_;
spyOn($state, 'go');
vm = $controller('SecurityController', {
});
}));
it('should be registered', () => {
expect(vm).toBeDefined();
});
});
Here is the controller code:
function SecurityController(){
'ngInject';
const vm = this;
vm.security = "secure";
}
export default SecurityController;
And here is the module code, for good measure:
import angular from 'angular';
import uiRouter from 'angular-ui-router';
import SecurityController from './securityController'
import SignUp from './services/signUpService';
import AuthenticationService from './services/authService'
const security = angular.module('security', [
uiRouter,
]).controller(SecurityController)
.service(SignUp)
.service(AuthenticationService);
export default security.name;
The security module is patched into my main app module, so I can provide that as well. I've read through a few resources regarding this, but nothing I've tried has been particularly helpful so far.
Thanks in advance!
.controller(SecurityController)
.service(SignUp)
.service(AuthenticationService);
should be
.controller('SecurityController', SecurityController)
.service('SignUp', SignUp)
.service('AuthenticationService', AuthenticationService);
You need to provide the name ov the controller/service, and then its implementation.

ES6 and angular using Factory from a separate file for a controller

using ES6 in my controller MyController I make an http request to retrieve a webapi json data.. works perfectly fine until..
I want to take this call and put it inside a service or a factory file outside of this controller file. I am not able to do so.. can someone guide me with this?
I have an app file that imports my controllers and other components like this
import "babel-polyfill";
import myController from "controllers";
import myFactory from "factories";
(function() {
'use strict';
config().ready.then(app => {
app.mod
.factory('myFactory', myFactory).controller('my ....
I tried to create a factory like so:
export default class myFactory{
constructor($http) {
this.$http = $http;
}
myData() {
$http.get("/source").success(function(data) {
vm.myData = data;
vm.view.dataTable = data
}).error(...);
}
}
from my controller I tried calling it:
import myFactory from "factory";
export default class myController{
constructor($http, $mdDialog, $mdToast) {
let getMyData = new myFactory;
getMyData.myData();
var vm = this;
vm.myJsonDataFromFactory .....
}
I tried to import the class to my app and then to my controller file.. none worked.
error at this point is: Error: _factory.myFactory is not a constructor

angular.js:68 Uncaught Error: [ng:areq] Argument 'fn' is not a function, got Object

I am converting our angular app to use ES6 Style syntax and after changing all the files i am getting the following error;
angular.js:68 Uncaught Error: [ng:areq] Argument 'fn' is not a function, got Object
When i tried to debug the error the error seems to be coming while creating a service. In angular code this is where the error is happening
return cache[serviceName] = factory(serviceName, caller);
i am seeing the serviceName getting passed fine, how ever the caller is undefined and not sure why factory is unable to return the service instance.
Thanks
Here is the complete code in my github account.
https://github.com/mars76/angular-es6
my entry point is app.js
import * as angular from 'angular';
import config from './app-config';
import run from './app-run-config';
import uiRouter from 'angular-ui-router';
import AppController from './app-controller';
import MyService from './my-service';
import * as serviceModule from './service';
import testDirective from './test-directive';
import muUtil from './util/util.js';
export default angular.module("my-app", ['ui.router','my-service-module','myUtil'])
.config(config)
.run(run)
.component('testDirective',testDirective())
.controller('appController', AppController).name;
And this has a dependency on module "myUtil"
and here are the contents of that module
./util/util.js
import * as utilRun from './util-run.js';
import * as MyService1 from './my-service1.js';
import * as MyService2 from './my-service2.js';
export default angular.module('myUtil', [])
.service('MyService1', MyService1)
.service('MyService2', MyService2)
.run(utilRun).name;
And here are my Services
Service 1:
export default class MyService1{
constructor(){
}
init(){
console.log('In MyService1()');
}
}
Service 2:
export default class MyService2{
constructor(){
}
init(){
console.log('In MyService2()');
}
}
And the run function of the util module
import MyService1 from './my-service1.js';
import MyService2 from './my-service2.js';
export default function utilRun(MyService1,MyService2){
MyService1.init();
MyService2.init();
}
utilRun.$inject =['MyService1','MyService2'];
I just had the same Problem. In my case it was just a problem with the imports.
This documentation helped me: import - JavaScript | MDN
The services are exported as default and should be imported in your ./util/util.js as default by:
import MyService1 from './my-service1.js';
import MyService2 from './my-service2.js';
I suggest the error
angular.js:68 Uncaught Error: [ng:areq] Argument 'fn' is not a function, got Object
had the reason, that the services were undefined when imported this way:
import * as MyService1 from './my-service1.js';
import * as MyService2 from './my-service2.js';
The wildcard import doesn't import defaults. That's the reason why there have to be a special case in the ES6 syntax:
import defaultMember, * as name from "module-name";

Resources