angular 2 service injection issue - javascript

My project structure:
app.component.ts:
import { Component } from "#angular/core"
import { Todo } from './components/shared/todo.model'
import { todos } from "./components/shared/todo.data"
import {TodoService} from "./components/shared/todoService"
import {TodoService} from "./components/shared/todoService";
#Component({
moduleId: module.id,
selector: "app",
templateUrl: "app.component.html",
styleUrls: ['app.component.css'],
providers: [TodoService]
})
export class AppComponent {
title:string = "Angular 2Do";
}
todo-form.component.ts:
import {Component, Output, EventEmitter} from "#angular/core";
import {Todo} from "../shared/todo.model";
import {TodoService} from "../shared/todoService"
#Component({
moduleId: module.id,
selector: "todo-form",
templateUrl: "todo-form.component.html",
styleUrls: ["todo-form.component.css"],
})
export class TodoForm {
...
constructor(private todoService:TodoService) {
console.log(this.todoService);
this.todoService.order = 2;
console.log( this.todoService);
}
}
todo-list.component.ts:
import {Component, Input, OnInit} from "#angular/core"
import { ITodo } from "../shared/todo.model"
import { TodoService } from "../shared/todoService"
#Component({
moduleId: module.id,
selector: "todo-list",
templateUrl: "todo-list.component.html",
styleUrls: ["todo-list.component.css"],
})
export class TodoListComponent implements OnInit {
todos:ITodo[];
...
constructor(private todoService:TodoService) {
...
console.log(this.todoService);
this.todoService.order=1;
console.log(this.todoService);
}
...
}
app is the parent of the list and form components
Whaen I start application I see in console:
but if expand all I see:
Which result actual and why in second view I see 1 and in another 2.

The console.log '+' button can only show you the current state of the object, not the object at the snapshot in time of when it was called.
See console.log() async or sync? for a more in depth explanation.
So order: 1, is the final state of the object.

never use providers( providers: [TodoService] ) in component
as
import { Component } from "#angular/core"
import { Todo } from './components/shared/todo.model'
import { todos } from "./components/shared/todo.data"
import {TodoService} from "./components/shared/todoService"
import {TodoService} from "./components/shared/todoService";
#Component({
moduleId: module.id,
selector: "app",
templateUrl: "app.component.html",
styleUrls: ['app.component.css']
})
export class AppComponent {
title:string = "Angular 2Do";
}
it makes new instance when component initialise so put providers in module only ie. NgModule

Related

Angular component is not rendering | angular 9.1.3

I am not able to render component header in my application. I don't get any error also. In browser, It shows the header tag also but text present in header.component.html is not shown.
app.modules.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { AppComponent } from './app.component';
import { HeaderComponent } from './header/header.component';
#NgModule({
imports: [ BrowserModule, FormsModule ],
bootstrap: [ AppComponent ],
declarations: [HeaderComponent]
})
export class AppModule { }
app.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'project',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Project';
}
app.component.html
<header></header>
<p>
Hello World
</p>
header.component.ts
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent{
}
Please help me. :'(

How to open modal window using angular4 and load component content?

I have imported ngbModal module fron ng2bootstrap now i am trying to open modal window and load the current component content into modal body. what is the correct approach to implement ?
search.components.ts
import { Component, OnInit,Pipe, PipeTransform, EventEmitter,Input, Output,OnChanges, SimpleChanges } from '#angular/core';
import {GtConfig} from '#angular-generic-table/core';
import {NgbModal} from '#ng-bootstrap/ng-bootstrap';
import * as io from 'socket.io-client';
#Component({
selector: 'app-detail',
templateUrl: './detail.component.html',
styleUrls: ['./detail.component.css'],
})
export class DetailComponent implements OnChanges{
constructor(private detailService: DetailService,private ngbModal: NgbModal) {};
ngOnInit(){
this.secondConfigObject = {
settings: this.getBaseSettings(),
fields: this.getBaseFields(),
data: []
};
})
}
rowData(event) {
console.log('Event',event);
this.detailService.changeChart(event);
}
execModal(evt){
const modalReg = this.ngbModal.open(Component);
}
}

Javascript Angular4 Service method not recognize

I have created a simple service using angular4
Here's the code:
//app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { MyserviceService } from './myservice.service';
import { AppComponent } from './app.component';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule
],
providers: [MyserviceService],
bootstrap: [AppComponent]
})
export class AppModule { }
//the service
import { Injectable } from '#angular/core';
#Injectable()
export class MyserviceService {
constructor() { }
cars = ['fiat', 'form'];
myData() {
return 'Hello from service!';
}
}
//app.component.ts
import { Component, OnInit } from '#angular/core';
import { MyserviceService } from './myservice.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'app';
constructor(private myservice: MyserviceService) {}
ngOnInit() {
console.log(this.myservice.cars);
this.something = this.myData();
}
}
I am having 2 problems here:
No console message
myData is not recognized 'myData does not exists in app.component'
What I'm I doing wrong here?
You are accessing myData() method on app.component, it is not a member of app component. you have to access myData() with myservice, like this
ngOnInit() {
console.log(this.myservice.cars);
this.something = this.myservice.myData();
}
and Everything else looks fine to me.

Vanilla NG2 component not displaying?

So in my angular 2 app I have:
//app.component.ts
import { Component } from '#angular/core';
import { sidebarComponent } from './sidebar/sidebar.component';
#Component({
selector: 'my-app',
template: `<sidebar></sidebar>
<h1>helps</h1>`,
providers: [sidebarComponent]
})
export class AppComponent { }
and
//sidebar.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'sidebar',
template: `<h1>sidebar</h1>`
})
export class sidebarComponent { }
When I load my app and app.component is displayed, I get <sidebar></sidebar><h1>helps</h1> rendered directly (in the page source), but no <h1>sidebar</h1>. What have I missed here?
What have I missed here? Directives :-)
import { Component } from '#angular/core';
import { sidebarComponent } from './sidebar/sidebar.component';
#Component({
selector: 'my-app',
template: `<sidebar></sidebar>
<h1>helps</h1>`,
directives: [sidebarComponent]
})
export class AppComponent { }
use directives:[sidebarComponent] instead of providers: [sidebarComponent]

How can I get a directive/component instance inside another component?

I have an AlertComponent that I would like to use as a directive in my AppComponent and expose it so that it's available (as a sort of singleton) to all the routes/children components from AppComponent. But I can't seem to find a way to get the instance of the AlertComponent object used as a directive in order to call it's methods and see the changes made on the directive (i.e. add/remove alerts to/from the page).
Here is AlertComponent:
import { Component } from 'angular2/core';
import { Alert } from './model';
#Component({
selector: 'alerts',
templateUrl: './alert/index.html'
})
export class AlertComponent {
alerts: Array<Alert>;
constructor() {}
add(alert: Alert) {
this.alerts.push(alert);
}
remove(index: number) {
this.alerts.splice(index, 1);
}
clear() {
this.alerts = [];
}
}
export { Alert };
And AppComponent:
import { Component, OnInit, provide } from 'angular2/core';
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router';
import { HTTP_PROVIDERS, RequestOptions } from 'angular2/http';
import { CookieService } from 'angular2-cookie/core';
import { UserComponent } from '../user/component';
import { AlertComponent, Alert } from '../alert/component';
import { ExtendedRequestOptions } from '../extended/RequestOptions';
import { UtilObservable } from '../util/observable';
#Component({
selector: 'app',
template: `
<alerts></alerts>
<router-outlet></router-outlet>
`,
//styleUrls: [ 'app/style.css' ],
directives: [
ROUTER_DIRECTIVES,
AlertComponent
],
providers: [
ROUTER_PROVIDERS,
HTTP_PROVIDERS,
provide(RequestOptions, { useClass: ExtendedRequestOptions }),
CookieService,
UtilObservable,
AlertComponent
]
})
#RouteConfig([{
path: '/user/:action',
name: 'User',
component: UserComponent,
useAsDefault: true
}
])
export class AppComponent implements OnInit {
constructor(public _alert: AlertComponent) {}
ngOnInit() {
this._alert.add(new Alert('success', 'Success!'));
}
}
I'd like to have the same instance of AlertComponent available to all descendant routes/children of AppComponent (e.g. UserComponent), so as to add alerts to the same directive.
Is this possible? Or is there another, more proper way to do this?
[Update]
The chosen solution answers the title question, but I also wanted to have a simple solution to share alerts among my components. Here's how to do that:
AlertComponent:
import { Component } from 'angular2/core';
import { Alert } from './model';
export class Alerts extends Array<Alert> {}
#Component({
selector: 'alerts',
templateUrl: './alert/index.html'
})
export class AlertComponent {
constructor(public alerts: Alerts) {}
add(alert: Alert) {
this.alerts.push(alert);
}
remove(index: number) {
this.alerts.splice(index, 1);
}
clear() {
this.alerts.length = 0;
}
}
export { Alert };
AppComponent:
import { Component, provide } from 'angular2/core';
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from 'angular2/router';
import { HTTP_PROVIDERS, RequestOptions } from 'angular2/http';
import { AlertComponent, Alerts } from '../alert/component'
import { UserComponent } from '../user/component';
import { ExtendedRequestOptions } from '../helpers/extensions';
#Component({
selector: 'app',
template: `<router-outlet></router-outlet>`,
directives: [
ROUTER_DIRECTIVES
],
viewProviders: [
provide(Alerts, { useValue: [] })
],
providers: [
ROUTER_PROVIDERS,
HTTP_PROVIDERS,
provide(RequestOptions, { useClass: ExtendedRequestOptions })
]
})
#RouteConfig([{
path: '/user/:action',
name: 'User',
component: UserComponent,
useAsDefault: true
}
])
export class AppComponent {}
Basically, I'm providing a singleton array of alerts that's used by every AlertComponent.
You can move the provide() to providers (instead of viewProviders) if you want to use it outside of directives, but if not, keep it simple and restrict it this way.
Hope this helps someone :)
You need to use ViewChild decorator to reference it:
#Component({
})
export class AppComponent implements OnInit {
#ViewChild(AlertComponent)
_alert: AlertComponent;
ngAfterViewInit() {
// Use _alert
this._alert.add(new Alert('success', 'Success!'));
}
}
#ViewChild is set before the ngAfterViewInit hook method is called.
expose it so that it's available (as a sort of singleton) to all the
routes/children components from AppComponent.
Or is there another, more proper way to do this?
Create and bootstrap a service for AlertComponent, like this
AlertService
import {Injectable} from '#angular/core';
import {Subject} from 'rxjs/Subject';
import 'rxjs/add/operator/share';
#Injectable()
export class AlertService {
private _alerts: Array<Alert> = [];
public alertsChange: Subject<Array<Alert>> = new Subject();
public get alerts(): Array<Alert> {
return this._alerts;
}
add(alert: Alert) {
this._alerts.push(alert);
this.alertsChange.next(this._alerts);
}
remove(index: number) {
this._alerts.splice(index, 1);
this.alertsChange.next(this._alerts);
}
clear() {
this._alerts = [];
this.alertsChange.next(this._alerts);
}
}
Bootstrap AlertService
import {bootstrap} from '#angular/platform-browser-dynamic';
import {YourApp} from 'path/to/YourApp-Component';
import { AlertService} from 'path/to/alert-service';
bootstrap(YourApp, [AlertService]);
AlertComponent
import { Component } from 'angular2/core';
import { Alert } from './model';
import { AlertService} from 'path/to/alert-service';
#Component({
selector: 'alerts',
templateUrl: './alert/index.html'
})
export class AlertComponent {
alerts: Array<Alert>;
constructor(alertService: AlertService) {
alertService.alertsChange.subscribe((moreAlerts: Array<Alert>) => {
this.alerts = moreAlerts;
})
}
}
All the routes/children components
(sample):
import { Component} from '#angular/core';
import { AlertService} from 'path/to/alert-service';
#Component({
template: `.....`
})
export class SampleComponent {
constructor(public alerts: AlertService){}
ngOnInit(){
this.alerts.add(new Alert('success', 'Success!'));
}
ngOnDestroy(){
this.alerts.clear();
}
}
To see other alike examples see this question

Categories

Resources