HttpClient: how to show data on DOM - javascript

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>

Related

property data of type Object is unreadable with ngFor

Angualr does not recognise the property data (dummy data from an API), i get the following error:
Property 'data' does not exist on type 'Object'
I tried removing the data property and just use "let user of users" but it gives me the following error on of : Type 'Object' is not assignable to type 'NgIterable | null | undefined'
my HTML component
<h1>Home</h1>
<ul *ngIf="users">
<li value="user" *ngFor="let user of users.data">
<img [src]="user.avatar">
<p>{{ user.first_name }} {{ user.last_name }}</p>
</li>
</ul>
the ts component :
import { Component, OnInit } from '#angular/core';
import { DataService } from '../data.service';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
users: Object;
constructor(private data: DataService) {
}
ngOnInit() {
this.data.getUsers().subscribe(data => {
this.users = data
console.log(this.users)
})
}
}
the Dataservice ts component:
import { Injectable } from '#angular/core';
import { HttpClient, HttpClientModule } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class DataService {
constructor(public http: HttpClient) { }
getUsers() {
return this.http.get('https://reqres.in/api/users')
}
}
Just make the following changes in your ts component to compile successfully
users : any ;
Or
create the interface as the sample response.

ANGULAR. Send array data get it of Itunes API; from component-search to component-main, via service

In angular 7. I need to send an Array information get it from Itunes Api, which is included in a component called "search", to another component called "catalog". I've understand that in this case I've to use a service which allows to share the info between them. Here's some code. What's wrong?
I've tried with viewchild, input, output, but there's no result; because both components aren't "relatives".
"search"
"search"
import { Component, OnInit, Output, EventEmitter } from '#angular/core';
import { RequestService } from '../../services/request/request.service';
import {DataShareService} from '../../services/dataShare/data-share.service';
import { Music } from '../../models/music';
#Component({
selector: 'search',
styleUrls: ['./ion-searchbar.component.sass'],
templateUrl: './ion-searchbar.component.html',
providers: [RequestService, DataShareService],
})
export class IonSearchBarComponent implements OnInit {
public searchResults: Music[];
public searchValue: string;
constructor(public _requestService: RequestService, private _dataShareService: DataShareService) {}
ngOnInit() {
this._dataShareService.$sendDataObservable.subscribe(
data => {
this.searchResults = data
})
}
sendData(searchResults: Music[]){
console.log("executat");
this._dataShareService.sendData(searchResults);
}
search(){
this._requestService.getMusic(this.searchValue).subscribe(
result => {
this.searchResults = result.results;
console.log(result.results);
this.sendData(this.searchResults);
},
error =>{
console.log(<any>error);
}
);
}
}
"service"
import { Injectable } from '#angular/core';
import { Music } from '../../models/music';
import { Subject } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class DataShareService {
private _sendDataSubject = new Subject<Music[]>();
$sendDataObservable = this._sendDataSubject.asObservable();
constructor() { }
sendData(data: Music[]){
this._sendDataSubject.next(data);
console.log(data);
}
}
"catalog"
import { Component, OnInit, Input } from '#angular/core';
import {RequestService} from '../../services/request/request.service';
import {DataShareService} from '../../services/dataShare/data-share.service';
import { Music } from '../../models/music';
#Component({
selector: 'catalog',
templateUrl: './catalog.component.html',
styleUrls: ['./catalog.component.sass'],
providers: [RequestService, DataShareService]
})
export class CatalogComponent implements OnInit {
public title: any;
public InfoLlegada: any;
constructor(private _dataShareService: DataShareService) {}
ngOnInit() {
console.log(this.InfoLlegada)
this._dataShareService.$sendDataObservable.subscribe(
data => {
this.InfoLlegada = data
console.log(data);
});
}
}
Not sure if this is the actual cause, but there an issue with your this binding in getMusic subscription in search component. Try this.sendData.call(this, result.results);

How to render a list retrieved from firebase

I want to render a list in angular project with data retrieved from firebase, but I cannot render it to my list.
I tried on Angular 7
//this is my ts code
import { Component } from '#angular/core';
import { AngularFireDatabase } from '#angular/fire/database';
import { PassThrough } from 'stream';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
courses: any[];
constructor(db: AngularFireDatabase) {
db.list('/courses').snapshotChanges().subscribe(courses =>{
this.courses = courses;
console.log(this.courses);
});
}
}
//this is the html
<ul>
<li *ngFor="let course of courses">
{{course.value}}
</li>
</ul>
I want it to show like this
course1
course2
but the list are rendered with only a dot like this
-
inside subscribe() this does not reference to courses you need to assign this to another variable like let self=this;
Try the following code i hope this will work for you
import { Component } from '#angular/core';
import { AngularFireDatabase } from '#angular/fire/database';
import { PassThrough } from 'stream';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
courses: any[];
constructor(db: AngularFireDatabase) {
let self=this;
db.list('/courses').snapshotChanges().subscribe(courses =>{
self.courses = courses;
console.log(courses);
});
}
}
Small issue, you cannot assign the node to this.courses
export class AppComponent {
courses: any[];
constructor(db: AngularFireDatabase) {
db.list('/courses').snapshotChanges().pipe(
map(changes =>
changes.map(c => ({ key: c.payload.key, ...c.payload.val() }))
)
).subscribe(courses =>{
this.courses = courses;
console.log(this.courses);
});
}
}
ref: https://github.com/angular/angularfire2/blob/master/docs/rtdb/lists.md
Also, make sure that course.value, "value" property exists in course object.
<ul>
<li *ngFor="let course of courses">
{{course.value}} <-- here ??
</li>
</ul>

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

Angular2 pipes dependency injection

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

Categories

Resources