How to use bootstrap in Angular 2 with vanilla js/es6? - javascript

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 {
(...)
}

Related

webpack error angular wrapper for native lib

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?

NestJS - Inject factory provider into another provider doesn't work

I'm trying to use nest custom provider with factory, for some reason I'm struggling to get it working.
I've created the following sample -
interface ProviderOptions: {x:string, y:number};
interface AsyncProps {useFactory:(...args:any[])=> ProviderOptions, inject:any[], imports:any[] }
#Module({})
export class MyModule {
static forRootAsync(asyncProps: AsyncProps): DynamicModule {
const myFactory: Provider = {
provide: "MY_PROVIDER",
useFactory: asyncProps.useFactory,
inject: asyncProps.inject,
};
return {
module: MyModule,
providers: [myFactory, MyService],
exports: [MyService],
imports: [...asyncProps.imports],
};
}
}
#Injectable()
export class MyService {
constructor(#Inject("MY_PROVIDER") this options:ProviderOptions){
}
}
For some reason I'm unable to resolve MyService -
Error: Nest can't resolve dependencies of the MyService (?). Please
make sure that the argument dependency at index [0] is available in
the MyModule context.
what I'm missing here?
Thanks!
UPDATE -
so now it's really strange -
originally MyService was in a different file, next to MyModule. when moved MyService to the same file as MyModule, the above code does work as expected. how can it be?
Based on your error, you have a circular file import which means that typecript can't resolve the class name and in turn Nest can't create the class. I just answered another question on it here

How to access external javascript file from angular 2 component

I am very new to angular and front end web development, so maybe i am missing something
basic but i did not succeed to search a solution for that issue.
according to that answer: Call pure javascript function from Angular 2 component
and following that example
I am trying to import external .js file to my angular component:
import '../../../src/Plugin/codemirror/mode/custom/custom.js'
#Component({
selector: 'txt-zone',
templateUrl: 'app/txtzone/Txtzone.component.html',
styleUrls: ['app/txtzone/TxtZone.css'],
})
the path is the correct relative path, i know that because if it loads diractly from the url text box via the browser [http://localhost:50371/src/Plugin/codemirror/mode/custom/custom.js]
i can see the file content...
this is the exception that the chrome debugger is throwing:
zone.js:2263 GET
http://localhost:50371/src/Plugin/codemirror/lib/codemirror 404 (Not
Found)
as you can see the path was changed (don`t understand why?)
1. how can i solve this issue?
2. why the path of the .js file is not the referenced path?
3. maybe there is a better way to load external .js file into my component?
it looks quite trivial question but after hours of searching i could not find any answer.
A simple way to include custom javascript functions in your Angular 4 project is to include the item in your assets folder, and then use require to import it into your component typescript.
src/assets/example.js
export function test() {
console.log('test');
}
src/app/app.component.ts
(before #Component(...))
declare var require: any;
const example = require('../assets/example');
(inside export class AppComponent implements OnInit { ...)
ngOnInit() {
example.test();
}

How to include external JavaScript libraries in Angular 2?

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);
}
}

Why I must add the tail 'Provider' to Service Name, when I used es6

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.

Categories

Resources