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
Related
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.
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>
I am using spring boot + angular.
Interpolation is not working for me. Whenever I reload the page I can see the changes in spring boot console but {{product.productId}} is not printing anything in the HTML page.
search.component.html
<div class="form- group col-md-4 offset-4 mt-4 card card-body">
<form >
<input type="text" name="search" [(ngModel)] ="search" placeholder="enter the products">
</form>
</div>
<div *ngFor="let products of products | filter:search" >
{{products.productId}}
</div>
search.component.ts
import { Component, OnInit } from '#angular/core';
import { ProductService } from '../product.service';
#Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.css']
})
export class SearchComponent implements OnInit {
products;
search:string;
constructor(private service: ProductService) { }
ngOnInit() {
this.service.getAllProducts().subscribe(data=>{
this.products = data ['products'];
});
}
}
product.service.ts (Service method)
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class ProductService {
private httpUrl = "http://localhost:8080/products"
constructor(private http: HttpClient) {}
getAllProducts(){
return this.http.get (`${this.httpUrl}`);
}
}
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './header/header.component';
import { SearchComponent } from './search/search.component';
import { AddProductComponent } from './add-product/add-product.component';
import { FilterPipe } from './filter.pipe';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { HttpClientModule } from '#angular/common/http';
import { ProductService } from './product.service';
#NgModule({
declarations: [
AppComponent,
HeaderComponent,
SearchComponent,
AddProductComponent,
FilterPipe
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule
],
providers: [ProductService],
bootstrap: [AppComponent]
})
export class AppModule { }
filter.pipe.ts
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'filter'
})
export class FilterPipe implements PipeTransform {
transform(products,search:string):any {
if(search){
return products.filter(product=>{
return product.name.toLowerCase().includes(search.toLowerCase())
});
}else{
return products;
}
}
}
I want to display products in search.component.html, everytime I reload the page I can see changes in backend(spring boot terminal) but it is not printing in html page through interpolation.
<div *ngFor="let product of products | filter:search" >
{{product.productId}}
</div>
Change this line.It will work for you.When u are iterating the names should be different.
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.
This is my HttpService.ts
import { Injectable } from "#angular/core";
import { Http, Response } from "#angular/http";
import 'rxjs/add/operator/map';
#Injectable()
export class HttpService {
constructor (private http: Http) {}
getData() {
return this.http.get('http://blog_api.org/v1/posts')
.map((response: Response) => response.json());
}
}
This is my app.component.ts
import { Component } from '#angular/core';
import { HttpService } from '../app/services/HttpService'
#Component({
selector: 'my-app',
template: `Hello`,
})
export class AppComponent {
constructor (private httpService: HttpService) {};
ngOnInit() {
this.httpService.getData()
.subscribe(
data => console.log(data)
)
}
}
When I running app, I get error:
EXCEPTION: No provider for HttpService!
In your AppModule you should be doing:
import {HttpService} from "...";
import {HttpModule} from "#angular/http";
#NgModule({
bootstrap: [...],
imports: [HttpModule],
declarations: [...],
entryComponents: [...],
providers: [HttpService]
})
export default class AppModule{}
You must provide the HttpService in the model that loads the app.component.ts.
In your case, as you are using app.component.ts, provide the http in app.module.ts. Something like:
import { HttpService } from '../app/services/HttpService'
#NgModule({
...
providers: [
...
HttpService,
]
})
export class AppModule { }
Add
providers: [HttpService]
in #Component block