Angular2 pipes dependency injection - javascript

hi all i am new to anguler 2 i am trying to create a custom pipe/filter
but when i want to inject the pipe i created inside app.ts it is not doable as in the attached image
my component code:
import { Component, OnInit ,Pipe, PipeTransform} from '#angular/core';
import { Input, Injectable, ApplicationRef, ChangeDetectorRef } from '#angular/core';
import {Observable} from 'rxjs/Rx'
import {Filter} from '../filter.pipe';
#Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.css'],
pipesp[Filter]
})
export class TestComponent implements PipeTransform {
private todos = ['wash dishes', 'Clean the ground','program the site', 'eat'];
constructor() {
}
transform(value: any) {
if (!value) {
return '';
}
}
}
filter.pipe.ts code :
import {Pipe, PipeTransform} from '#angular/core';
#Pipe({name:'filter'})
export class Filter {
transform(value,args){
if(!args[0]){
return value;
}else if ( value){
return value.filter(item => {
for(let key in item){
if((typeof item[key] === 'string' || item[key] instanceof String) && (item[key].indexOf(args[0]) !==-1)){
return true;
}
}
});
}
}
}
test.component.html
<input type="text" [(ngModel)]="filterText">
<ul>
<li *ngFor="let todo of todos | filter: filterText ">
{{todo}}
</li>
</ul>

You should inject the Pipe to the corresponding module as follows, and use it in the component
declarations: [
Filter
]

You need to include Pipe Component in Ng Module(in root component module) and use it as globally in all components
#NgModule({
imports: [ BrowserModule ],
declarations: [ SearchPipe ],
bootstrap: [ AppComponent ]
})
And use it in template directly
#Component({
selector: 'my-app',
template: '<p>My name is <strong>{{ name | search}}</strong>.</p>',
})

Here is a solution
Write
#Component({
pipes: [ filter ]
})
But not
#Component({
pipes[Filter]
})

Related

HttpClient: how to show data on DOM

This is an employee list from my mock db.json. I am trying to visualise it in the DOM.
In the app.component.html if I write in the loop {{employee}}, it visualises a list of 2 items and each item is[object Object]. Otherwise if I write {{employee.name}} the error is:
Property 'name' does not exist on type 'EmployeeService'.ngtsc(2339)
What am I missing? Any help will be appreciated.Thank you.
app.component.html:
{{title}}
<li *ngFor="let employee of employees">{{employee.name}}</li> //error with property name
app.component.ts
import { Component } from '#angular/core';
import { EmployeeService } from './service/employee.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'List of employees';
employees: EmployeeService[]=[];
constructor(private employeeService: EmployeeService) {}
ngOnInit(): void {
this.employeeService.getUsers().subscribe(emp => {
this.employees = emp;
})
}
}
employee.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class EmployeeService {
constructor(private http: HttpClient) { }
getUsers(): Observable<EmployeeService[]> {
return this.http.get<EmployeeService[]>('http://localhost:3000/employees')
}
}
db.json:
{
"employees": [
{
"id": 1,
"name": "Tim",
"hired": true
},
{
"id": 2,
"name": "Jess",
"hired": true
}
]
}
You could always see the data loaded to the template file using the json pipe operator,
Example <div>{{employees | json }}</div> , this will help you to understand the structure of data and access it correctly.
Solution to your problem:
The response from your getUsers() returns an object, that contains an array for employees. You were trying to access the data object.
Instead, you should retrieve the employees data from the object and loop through the employees data in your template file.
In your app.component.ts component:
import { Component } from '#angular/core';
import { EmployeeService } from './service/employee.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'List of employees';
employees: any[]=[]; // preferably a custom type/interface than 'any'
constructor(private employeeService: EmployeeService) {}
ngOnInit(): void {
this.employeeService.getUsers().subscribe(emp => {
this.employees = emp.employees; // ------------------> Change
})
}
}
Inside your app.component.html template:
<div *ngFor="let employee of employees">{{ employee.name }}</div>
In your employee.service.ts service
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class EmployeeService {
constructor(private http: HttpClient) { }
// Your custom interface/type should be the return type
getUsers(): Observable<any[]> {
return this.http.get('http://localhost:3000/employees');
}
}
Working app in Stackblitz
// check whether the employee list is not empty before rendering it in UI
<ul *ngIf="employees">
<li *ngFor="let employee of employees">{{ employee.name }}</li>
</ul>
// To view complete JSON dump in web page follow below: Add this import statement to your app module
import { CommonModule } from '#angular/common';
then include it in imports
#NgModule({
...,
imports: [CommonModule, ...],
})
<!-- in your app.html: -->
<div *ngIf ="employees">
{{ employees | json}}
</div>

adding html tag inside typescript file in angular

i am using angular2 so i want to implement html tag inside the return function in ts file
tooltip: (param: any) => {
return `<span> ${param.value} </span>`;
}
i have tried to use template literal but that make my span visible.
is there any idea how can i use the span proper way
try this code
stackblitz example
import {Component, NgModule, Pipe, PipeTransform} from '#angular/core'
import {BrowserModule} from '#angular/platform-browser'
import { FormsModule } from '#angular/forms';
import { DomSanitizer } from '#angular/platform-browser'
#Pipe({ name: 'safeHtml'})
export class SafeHtmlPipe implements PipeTransform {
constructor(private sanitized: DomSanitizer) {}
transform(value) {
console.log(this.sanitized.bypassSecurityTrustHtml(value))
return this.sanitized.bypassSecurityTrustHtml(value);
}
}
#Component({
selector: 'my-app',
template: `<div [innerHtml]="tooltip('Hello World') | safeHtml">
</div>`,
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
tooltip(param: any) {
return `<span> ${param} </span>`;
}
}

How to bind an HTTP Angular 4/5 request to html?

I have returned some raw JSON from an angular HTTPClient GET request and I am unsure how to now bind the properties of my JSON object to my html dynamically.
I would usually think to just store the returned JSON object into a variable and then reference it where I need it using dot notation, but Angular doesn't seem to work that way as I cannot set my http get request to a variable in ngOnInit and reference it.
I am using ngOnInit to initialize it when my Component loads and it is successfully logging to the console, but how do I get it binded INTO my html?
app.component.ts:
import { Component } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'Contacts';
constructor (private httpClient: HttpClient) {}
ngOnInit(): void {
this.httpClient.get('**URL PATH RETURNING JSON OBJECT**')
.subscribe((data) => {
console.log(data));
}
}
app.module.ts:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { HttpClientModule } from '#angular/common/http';
import { AppComponent } from './app.component';
#NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
HTML:
<div id= contacts-container>
<header><h1> {{ title }} </h1></header>
<div id= "favoritesContainer">
<p>Favorite Contacts</p>
</div>
<ul>
<li *ngFor="let contact of contacts">
<div *ngIf= "!contact.isFavorite">
<img src={{contact.smallImageURL}} />
<h3><img src="../assets/Favorite Star (True)/Favorite — True.png">{{ contact.name }} </h3>
<br>
<p>{{ contact.companyName }}</p>
<hr>
</div>
</li>
</ul>
</div>
You don't seem to have a contacts variable in your app.component.ts.
This is what it should look like:
export class AppComponent {
title = 'Contacts';
contacts: any[]; // Add variable
constructor (private httpClient: HttpClient) {}
ngOnInit(): void {
this.httpClient.get('**URL PATH RETURNING JSON OBJECT**')
.subscribe((data)=>{
console.log(data);
this.contacts = data; // Once you get the data, assign the data returned to contacts
});
}
}
Try like this :
import { Component } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'Contacts';
constructor (private httpClient: HttpClient) {}
ngOnInit(): void {
this.httpClient.get('**URL PATH RETURNING JSON OBJECT**')
.subscribe((data)=>{
this.contacts = data;//I have assigned data here inside subscription
console.log(data);
});
}
}
and reference this.contacts in same way you are doing in HTML

Uncaught Error: Template parse errors: Angular 4

I have been trying to make a simple app in Angular, I was able to make it work in Plunker. Unfortunately, it gives me this error
Can't bind to 'joke' since it isn't a known property of 'app-root'.
that I don't know how to handle.
What is the problem?
joke.component.ts
import { Component, EventEmitter, Input, Output, OnInit } from '#angular/core';
import { Joke } from '../jokes'
#Component({
selector: 'app-joke',
templateUrl: './joke.component.html',
styleUrls: ['./joke.component.css']
})
export class JokeComponent implements OnInit {
constructor() {}
#Input("joke") joke: Joke;
#Output() jokeDeleted = new EventEmitter<Joke>();
deleteItem() {
this.jokeDeleted.emit(this.joke)
}
ngOnInit() {}
}
joke-form.component.spec
import { async, ComponentFixture, TestBed } from '#angular/core/testing';
import { JokeFormComponent } from './joke-form.component';
describe('JokeFormComponent', () => {
let component: JokeFormComponent;
let fixture: ComponentFixture<JokeFormComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ JokeFormComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(JokeFormComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});
joke-list.component
import { Component, OnInit } from '#angular/core';
import {Joke} from '../jokes';
#Component({
selector: 'app-joke-list',
templateUrl: './joke-list.component.html',
styleUrls: ['./joke-list.component.css']
})
export class JokeListComponent implements OnInit{
jokes: Joke[];
constructor() {
this.jokes = [
new Joke("I am telling a joke.", "Haha, that's funny!"),
new Joke("I am telling an even funnier joke.", "Hahahahaha!!"),
new Joke("I am telling the funniest joke.", "HAHAHAHAHAHA!!!!")
]
}
addJoke(joke) {
this.jokes.unshift(joke);
}
deleteJoke(joke) {
let indexToDelete = this.jokes.indexOf(joke)
if (indexToDelete !== -1) {
this.jokes.splice(indexToDelete, 1);
}
}
ngOnInit() {}
}
app.component
import { Component } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {}
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { HttpModule } from '#angular/http';
import { AppComponent } from './app.component';
import { JokeFormComponent } from './joke-form/joke-form.component';
import { JokeListComponent } from './joke-list/joke-list.component';
import { JokeComponent } from './joke/joke.component';
#NgModule({
declarations: [
AppComponent,
JokeFormComponent,
JokeListComponent,
JokeComponent,
],
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
HttpModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
From the code you have posted I see that your AppComponent class is empty :
export class AppComponent {}
Since you haven't posted your html code, I am guessing you are doing something similar to the plunker, where my-app in plunker is equivalent to app-root in your question's code:
<app-root *ngFor="let j of jokes" [joke]="j" (jokeDeleted)="deleteJoke($event)"></app-root>
Once you add #Input("joke") joke: Joke to AppComponent class, it should not throw that error anymore:
export class AppComponent {
#Input("joke") joke: Joke;
#Output() jokeDeleted = new EventEmitter<Joke>();
deleteItem() {
this.jokeDeleted.emit(this.joke)
}
}
You can try to delete this OnInit method that angular generates for us in this child joke.component.ts class that implements this #Input method for Property binding [property]. And also restart the server.

Creating Dynamic Components Angular Cli

I want to create Dynamic components and previously when i was working with Angular 2, I used this piece of code from another stack-overflow answer which worked fine until i switched to Angular-cli. How can i make it work in angular cli?
import {
Component,
Directive,
NgModule,
Input,
ViewContainerRef,
Compiler
} from '#angular/core';
import { CommonModule } from '#angular/common';
#Directive({
selector: 'html-outlet'
})
export class HtmlOutlet {
#Input() html: string;
constructor(private vcRef: ViewContainerRef, private compiler: Compiler) {}
ngOnChanges() {
const html = this.html;
if (!html) return;
#Component({
selector: 'dynamic-comp',
templateUrl: html
})
class DynamicHtmlComponent { };
#NgModule({
imports: [CommonModule],
declarations: [DynamicHtmlComponent]
})
class DynamicHtmlModule {}
this.compiler.compileModuleAndAllComponentsAsync(DynamicHtmlModule)
.then(factory => {
const compFactory = factory.componentFactories.find(x => x.componentType === DynamicHtmlComponent);
this.vcRef.clear();
const cmpRef = this.vcRef.createComponent(compFactory, 0);
});
}
}

Categories

Resources