I have created a Service for an Angular App which is working fine as expected.
Its a Notification Service Wrapper for the package 'awesome-notifications'.
If I transfer the Service to the lib and use it from the lib i am getting kind of an import error its telling me something like constructor is not defined. Its referencing to the line :
'import AWN from "awesome-notifications"' which is the first line of the service.
its needed to create the notifier in the Service. Because its a Wrapper.
it seems like angular can not inject the service i wrote.
But if i am using it in an existing app it works, its really strange. does someone have experience with that ?
Code
import { Injectable } from '#angular/core';
import AWN from 'awesome-notifications';
export interface NotificationRequestModel {
message:string;
title?:string;
}
#Injectable({
providedIn: 'root'
})
export class NotificationService {
notifier = new AWN();
constructor() {
}
success(req:NotificationRequestModel) {
this.notifier.success(req.message, {
labels: { success: req?.title },
})
} etc..
ERROR TypeError: awesome_notifications__WEBPACK_IMPORTED_MODULE_0__ is not a constructor
This looks like a build/bundle issue with webpack/typescript. Since one can't reproduce your setup you should provide an example with more information. Its probably the default import for your native library. I can only guess:
Do you have allowSyntheticDefaultImports set in your ts config?
Related
I'm trying to implement an Angular 2 app without TypeScript and I'm stuck in how to bootstrap it (can find any example).
My app (without the bootstrap()) starts with:
export class MyApp {
static get parameters() {
return [[Http], [Platform], [IonicApp]];
}
constructor(http, platform, app) {
}
}
this works ok.
But, let's say, I have a CustomService. How would I do to inject it to MyApp?
I tried with:
bootstrap(myApp, [SomeCustomService]);
but the console logs:
EXCEPTION: No provider for Http! (MyApp -> Http)
I'm I missing something? Did I understood worng some concepts?
You need to add HTTP_PROVIDERS when bootstrapping your application:
bootstrap(myApp, [HTTP_PROVIDERS, SomeCustomService]);
Note that with Ionic2, there is no need to bootstrap your application. You can simply specify global providers on the class decorated with #App:
#App({
(...)
providers: [HTTP_PROVIDERS, SomeCustomService]
})
export class MyApp {
(...)
}
I am trying to include an external JS library in my Angular 2 app and trying to make all the methods in that JS file as a service in Angular 2 app.
For eg: lets say my JS file contains.
var hello = {
helloworld : function(){
console.log('helloworld');
},
gmorning : function(){
console.log('good morning');
}
}
So I am trying to use this JS file and reuse all the methods in this object and add it to a service, so that my service has public methods, which in turn calls this JS methods. I am trying to reuse the code, without reimplementing all the methods in my typescript based Angular 2 app. I am dependent on an external library, which I cant modify.
Please help, thank you in advance.
With ES6, you could export your variable:
export var hello = {
(...)
};
and import it like this into another module:
import {hello} from './hello-module';
assuming that the first module is located into the hello-module.js file and in the same folder than the second one. It's not necessary to have them in the same folder (you can do something like that: import {hello} from '../folder/hello-module';). What is important is that the folder is correctly handled by SystemJS (for example with the configuration in the packages block).
When using external libs which are loaded into the browser externally (e.g. by the index.html) you just need to say your services/component that it is defined via "declare" and then just use it. For example I recently used socket.io in my angular2 component:
import { Component, Input, Observable, AfterContentInit } from angular2/angular2';
import { Http } from 'angular2/http';
//needed to use socket.io! io is globally known by the browser!
declare var io:any;
#Component({
selector: 'my-weather-cmp',
template: `...`
})
export class WeatherComp implements AfterContentInit{
//the socket.io connection
public weather:any;
//the temperature stream as Observable
public temperature:Observable<number>;
//#Input() isn't set yet
constructor(public http: Http) {
const BASE_URL = 'ws://'+location.hostname+':'+location.port;
this.weather = io(BASE_URL+'/weather');
//log any messages from the message event of socket.io
this.weather.on('message', (data:any) =>{
console.log(data);
});
}
//#Input() is set now!
ngAfterContentInit():void {
//add Observable
this.temperature = Observable.fromEvent(this.weather, this.city);
}
}
I am getting the following errors in my browser console, from trying to use localStorage with Angular2. It seems that the path it is generating isn't referring to the node_modules, but rather assuming that there is a localstorage.js in my site root (which there isn't). I am just referring to it normally (see my user.service below), so how do I get around this? All my other dependencies are working fine.
Error loading http://localhost:3000/localStorage.js as "localStorage" from http://localhost:3000/client/dev/user/services/user.service.js
import { Injectable } from 'angular2/core';
import { Headers } from 'angular2/http';
import { loalStorage } from 'localStorage';
#Injectable()
export class UserService {
private loggedIn = false;
constructor(private http: Http) {
this.loggedIn = !!localStorage.getItem('auth_token');
}
}
NB: I am fairly sure there isn't an actual problem with the localStorage installation, as if I run npm list localStorage, then it tells me I have localStorage#1.0.3 instaled.
If you want to use localStorage from an import, you need to configure it within SystemJS as described below:
System.config({
map: {
localStorage: 'node_modules/localStorage/lib/localStorage.js'
},
(...)
});
This way, you will be able to use the following import:
import loalStorage from 'localStorage';
See this question for more details since it's similar to the way to configure Lodash:
Lodash in angular2, declare var_:any not working
am trying to import JS sdk into ionic 2 app, but i keep getting parse is undefined
In ionic 1.x ,parse js sdk is loaded via
<script ..parse.js </script>
and exposed as a global var, how do import in ionic 2 ,am using the npm module ,and tried
import * as parse from 'parse'
Do npm install parse --save in your project directory
Then import parse using
import { Parse } from 'parse';
It is better to create an parse provider.
You can use this starter template as a guide. It is a simple GameScores application in ionic to get you started.
https://github.com/Reinsys/Ionic-Parse
It shows how to create and read data from parse server. I also includes paging with ion-infinite-scroll scrolling.
After searching for a solution I came up with my own.
After installing the package and the typings, I opened the index.js of the node-module ionic-gulp-scripts-copy and added 'node_modules/parse/dist/parse.min.js' to the defaultSrc array.
Then, in my index.html, I included the script above the cordova.js.
Now I just need to declare var Parse: any; in every Component I want to use the SDK in.
For example, in my app.ts:
import {Component} from '#angular/core';
import {Platform, ionicBootstrap} from 'ionic-angular';
import {StatusBar} from 'ionic-native';
import {TabsPage} from './pages/tabs/tabs';
import{LoginPage} from './pages/login/login';
declare var Parse: any;
#Component({
template: '<ion-nav [root]="rootPage"></ion-nav>',
})
export class MyApp {
private rootPage: any;
private parse;
constructor(private platform: Platform) {
//this.rootPage = TabsPage;
this.rootPage = LoginPage;
platform.ready().then(() => {
console.log("Platform ready!");
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
StatusBar.styleDefault();
Parse.initialize('myStartUp', 'someKey');
Parse.serverURL = 'http://localhost:1337/parse';
});
}
}
ionicBootstrap(MyApp);
I do not think this is the way it should be used, but in the end I can use the SDK pretty easy and without much lines of implementation code.
My angular version is 1.4.8.
I have a service defined with es-6 class
class OrdersService {
...
}
export default angular.module('services.orders', [])
.service('ordersService', OrdersService)
.name;
I want inject it to a other module
import ordersService from 'orders.service'
function routes($stateProvider, ordersService) {
....
}
routes.$inject = ['$stateProvider', 'ordersService'];
export default angular
.module('orders',[ordersService])
.config(routes)
But Angular throw a exception said 'Couldn't found provider orderService'. But add tail 'Provider' to service made it work.
routes.$inject = ['$stateProvider', 'ordersServiceProvider'];
In this article, author don't add but still work.
http://angular-tips.com/blog/2015/06/using-angular-1-dot-x-with-es6-and-webpack/
class RandomNames {
....
}
export default angular.module('services.random-names', [])
.service('randomNames', RandomNames)
.name;
import randomNames from 'randomNames'
export default class HomeController {
....
}
HomeController.$inject = ['randomNames'];
Why I need to add 'Provider' to a service? Is there a api doc to declare that?
During the angular config phase you may only use providers. Using .service (or .factory) is shorthand for creating a provider. You can also use .provder but then you have to create the provider more explicitly.
Providers and the .config phase are used for configuration of services for use in the app. Since you are not doing any configuration, you get no benefit from injecting the orderService into .config.
Perhaps you could inject it into .run
You can use ngAnotate instead of doing this manually.
Add special comment on your constructor:
export default class HomeController {
/*#ngInject*/
constructor(randomNames) {
this.randomNames = randomNames;
}
}
Then add ng-annotate plugin to your build process and it will describe that injections for you.