Call JSON with subscribe or promise - json

If I use the promise function, I get the Error:
**Property 'TEST' does not exist on type 'Object'**
my ServiceClass
with the method:
getTEST() {
return this.http.get(this.configUrl)
.toPromise()
.then(res => <Tariftabelle[]> res.TEST)
.then(data => { return data; });
}
And my json-Date:
{
"TEST": [
{"leistung": "hello", "sb": "World"},
{"leistung": "hellooo", "sb": "Test-Wordl"}
],
"TEST2": [
{"leistung": "hola", "basic": "1", "premium": "2", "exzellent": "3"},
{"leistung": "hola two", "basic": "2", "premium": "4", "exzellent": "6"},
{"leistung": "hola three", "basic": "4", "premium": "7", "exzellent": "9"}
]
}
or how can iIuse subscribe without promise?

Service
#Injectable({
providedIn: 'root'
})
export class MyService {
getTEST(): Observable<any> {
return this.http.get(this.configUrl);
}
}
Component
#Component({
selector: 'app-my-component',
templateUrl: './my-component.html',
styleUrls: ['./my-component.scss']
})
export class MyComponent implements OnInit {
data: any;
constructor(private myServ: MyService) {}
ngOnInit() {
this.myServ.getTEST().subscribe(res => {
this.data = res;
});
}
}
Template
<pre>{{ data | json }}</pre>
As you can see in the init of your component you subscribe for the service getTEST request. In the subscribe, when you receive json data, you assign them to your local data variable. Now you can access it into your template.

Related

Angular problem: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays

I am pretty new with Angular and I stuck with problem building up my portfolio project. The problem is with receiving list of (nested) objects like this:
"$id": "1",
"data": {
"$id": "2",
"$values": [
{
"$id": "3",
"id": 1,
"name": "producto",
"shortDescription": "prod11111",
"longDescription": "lorem ipsum bla bla",
"category": "1",
"price": 50.00,
"stockLevel": 10,
"orderDetails": {
"$id": "4",
"$values": []
}
},
{
"$id": "5",
"id": 2,
"name": "segundo",
"shortDescription": "prod222",
"longDescription": "lorem ipsum",
"category": "2",
"price": 30.00,
"stockLevel": 20,
"orderDetails": {
"$id": "6",
"$values": []
}
}
]
},
"error": null
}
This is my app.component.ts:
import { HttpClient } from '#angular/common/http';
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
title = 'Shop';
products: any[] = [];
constructor(private http: HttpClient) {}
ngOnInit(): void {
this.http.get('https://localhost:5001/api/products').subscribe((response: any) => {
this.products = response.data;
}, error => {
console.log(error);
});
}
}
This is app.component.html:
<app-nav-bar></app-nav-bar>
<div class="container" style="margin-top: 140px;">
<h1>Welcome to {{title}}!</h1>
<ul>
<li class="list-unstyled" *ngFor="let product of products">
{{product.name}}
</li>
</ul>
</div>
I looked thru StackOverflow for similar problems but cannot resolve this in my case.
I think that there is problem because of arrays of arrays or nested objects.
Any help is appreciated!
The response.data is not an array. Instead, I believe that response.data.$values is what you need for the products array.
this.http.get('https://localhost:5001/api/products').subscribe((response: any) => {
this.products = response.data.$values;
}, error => {
console.log(error);
});

Angular Response error : SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse

I want get my data from an API. The API itself works fine in postmap like this :
{
"status": "Success",
"data": [
{
"title": "asus g551 vw",
"price": 500,
"image": "https://localhost:44345/images/products/origin/img1.jpg",
"count": 2
},
{
"title": "asus vivobook",
"price": 1200,
"image": "https://localhost:44345/images/products/origin/img1.jpg",
"count": 2
},
{
"title": "acer predator",
"price": 200,
"image": "https://localhost:44345/images/products/origin/img1.jpg",
"count": 1
}
]
}
But in Angular, when I call my get function, I get an error from this Angular code :
myservice method 'GetUserBasketDetails()' :
#Injectable({
providedIn: 'root'
})
export class OrderService {
private orderDetails : BehaviorSubject<OrderBasketDto[]> = new BehaviorSubject<OrderBasketDto[]>(null);
constructor(private _http : HttpClient) { }
_SetOrderDetails(details : OrderBasketDto[]){
this.orderDetails.next(details);
console.log(this.orderDetails)
}
_GetOrderDetails() : Observable<OrderBasketDto[]>{
return this.orderDetails;
}
GetUserBasketDetails():Observable<IResponseResult<OrderBasketDto[]>>{
return this._http.get<IResponseResult<OrderBasketDto[]>>('/basket-details');
}
}
when I call it in a component :
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
title = 'Front-Project';
constructor(private _accountService : AccountService,
private _orderService : OrderService) {
}
ngOnInit():void {
this._orderService.GetUserBasketDetails().subscribe(res=>{
console.log(res)
})
}
}
This is the error I get:
HttpErrorResponse {headers: HttpHeaders, status: 200, statusText: "OK", url: "https://localhost:44345/basket-details", ok: false, …}
and
Error: SyntaxError: Unexpected token < in JSON at position 0 at JSON.parse () at XMLHttpRequest.onLoad (http://localhost:4200/vendor.js:20175:51) at ZoneDelegate.invokeTask (http://localhost:4200/polyfills.js:10720:31)
in console
console error image
How can I fix this?
I found th problem my url was wrong i forgot to add api controller name in get method
like this '/order/basket-details'

Pushing json file into a localStorage array

I have a task to make CRUD app in angular 8 but I have to push somehow my JSON file into local storage and then be able to add new objects. I made an array of contacts and put some data in there and if someone can help me to put this JSON data in that array of objects, so I can read all my contacts from localStorage.
I have tried to subscribe to contacts and it kinda works but won't add data to a localStorage.
Contacts Service
import { Contact } from '../models/contact';
import { IContact } from '../models/contact';
import { Observable } from 'rxjs/Observable';
import { HttpClient } from '#angular/common/http';
import { Injectable, OnInit } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class ContactService {
contacts: Array < Contact > = [{
first_name: "Darko",
last_name: "Lesevic",
emails: ["darko1#test.com", "darko2#test.com"],
phones: [123456789, 123456789, 123456789],
photo: ''
}];
constructor(private http: HttpClient) {
//this won't work
// this.getJSON().subscribe(data => {
// this.contacts = data;
// console.log(data);
// });
}
getJSON(): Observable < Contact[] > {
return this.http.get < Contact[] > ("/assets/data/contacts.json");
}
contacts_serialized: any;
contacts_deserialized: any;
localStorageObj() {
this.contacts_serialized = JSON.stringify(this.contacts); //converts data to string
localStorage.setItem('id', this.contacts_serialized);
this.contacts_deserialized = JSON.parse(localStorage.getItem('id')); //converts string to data
console.log(this.contacts_deserialized);
}
}
Calling contact Service here
import { ContactService } from '../services/contact.service';
import { Component, OnInit } from '#angular/core';
import { Observable } from 'rxjs';
import { Contact } from '../models/contact';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
constructor(private contactService: ContactService) { }
ngOnInit() {
this.contactService.localStorageObj();
}
}
MY JSON FILE
[{
"first_name": "Afonso",
"last_name": "Pinto",
"emails": ["mail01#gmail.com", "mail02#gmail.com"],
"phones": ["123-234-566", "123-234-567", "123-234-568"],
"photo": "http://lorempixel.com/400/300/people/"
},
{
"first_name": "Alexandre",
"last_name": "Paiva",
"emails": ["mail01#gmail.com"],
"phones": ["123-234-560", "123-234-561"],
"photo": null
},
{
"first_name": "Oea",
"last_name": "Romana",
"emails": ["mail01#gmail.com", "mail02#gmail.com"],
"phones": ["123-234-566", "123-234-567", "123-234-568"],
"photo": "http://lorempixel.com/400/300/people/"
},
{
"first_name": "Nuria",
"last_name": "Pelayo",
"emails": ["mail01#gmail.com", "mail02#gmail.com"],
"phones": ["123-234-568"],
"photo": "http://lorempixel.com/400/300/people/"
},
{
"first_name": "Lisandro",
"last_name": "Matos",
"emails": ["mail01#gmail.com", "mail02#gmail.com"],
"phones": ["123-234-566", "123-234-567"],
"photo": null
}
]
First of all, you need to subscribe and then use setItem
this.contactService.getJSON().subscribe((data) => {
localStorage.setItem('myData', JSON.stringify(data);
});

How to pass data received from service to angular datatable

I have just started working on Angular 4 and I am trying to render some data which I receive from angular service in json format, into angular-datatable, but whichever option i try its not working for me.
The table is coming, the columns are coming, however the data inside the columns are not displaying.
Any help would be great,
Thanks in advance..!!!!
Please find my code below:
component.html
<table datatable [dtOptions]="dtOptions" class="row-border hover"></table>
component.ts
import { Component, OnInit } from '#angular/core';
import { FleetDataService } from '../../services/fleet-data.service';
import { Subject } from 'rxjs/Subject';
#Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.scss']
})
export class DashboardComponent implements OnInit {
private fleetData: any;
dtOptions: DataTables.Settings = {};
dtTrigger: Subject<any> = new Subject();
constructor(private getFleetData:FleetDataService) { }
ngOnInit() {
this.getFleetData.getFleetData().subscribe(
fleetData => {
this.fleetData = fleetData;
console.log(this.fleetData);
this.dtTrigger.next();
},
err => {
console.log(err);
}
);
this.dtOptions = {
pagingType: 'full_numbers',
columns: [{
title: 'First Name',
data: this.fleetData
}, {
title: 'Last Name',
data: this.fleetData
}, {
title: 'Score',
data: this.fleetData
}]
};
}
}
component.service
import { Injectable } from '#angular/core';
import { HttpModule, Http, Response, Headers, RequestOptions } from
'#angular/http';
import { Observable } from 'rxjs/Rx';
#Injectable()
export class FleetDataService {
constructor(private http: Http) { }
getFleetData() {
return this.http.get("../../assets/data/test.json")
.map((res:Response) => res.json())
.catch((error:any) => Observable.throw(error.json().error || 'Server
Error'));
}
}
test.json
[{
"FirstName": "Jill",
"LastName": "Smith",
"Score": "disqualified"
}, {
"FirstName": "Eve",
"LastName": "Jackson",
"Score": "94"
}, {
"FirstName": "John",
"LastName": "Doe",
"Score": "80"
}, {
"FirstName": "Adam",
"LastName": "Johnson",
"Score": "67"
}]
You set your dtOptions outside the subscribe.
If you do this the fleetData stays empty so dtOptions is never set correctly, because an Observable is asynchronous. I propose this code:
export class DashboardComponent implements OnInit {
dtOptions: DataTables.Settings = {};
dtTrigger: Subject<any> = new Subject();
constructor(private getFleetData:FleetDataService) { }
ngOnInit() {
this.getFleetData.getFleetData().subscribe(
fleetData => {
console.log(fleetData);
this.buildDtOptions(fleetData)
this.dtTrigger.next();
},
err => {
console.log(err);
});
}
private buildDtOptions(fleetData: any): void {
this.dtOptions = {
pagingType: 'full_numbers',
columns: [
{title: 'First Name', data: fleetData},
{title: 'Last Name', data: fleetData},
{title: 'Score', data: fleetData}
]
};
}
}
For this error: ERROR TypeError: Cannot read property 'aDataSort' of undefined. You can do a spinner (ngIf / else) in the view and when data are loaded you display the datatable

Angular map function is returning "undefined is not a function"

I'm following this tutorial https://www.barbarianmeetscoding.com/blog/2016/04/02/getting-started-with-angular-2-step-by-step-6-consuming-real-data-with-http/, with Angular2 and VS Code.
I created a db.json server to test an api with, with the test data looking like
{
"articles": [{
"id": 1,
"name": "Wand of Lightning",
"description": "A powerful wand of ligthning.",
"price": 50,
"imageUrl": "/assets/images/wand.png",
"specs": [{
"name": "weight",
"value": 10
}, {
"name": "height",
"value": 22
}, {
"name": "material",
"value": "wood"
}],
"reviews": [{
"author": "Jaime",
"title": "I loved it!",
"content": "I loved the wand of ligthning! I usually use it to charge my laptop batteries!",
"rating": 5
}, {
"author": "John Doe",
"title": "Underwhelming",
"content": "I didn't like it at all...",
"rating": 1
}]
}, {
"id": 2,
"name": "Staff of Fire",
"description": "A powerful staff of fire.",
"price": 150,
"imageUrl": "/assets/images/staff-of-fire.png",
"specs": [{
"name": "weight",
"value": 10
}, {
"name": "height",
"value": 22
}, {
"name": "material",
"value": "wood and alabaster"
}],
"reviews": [{
"author": "Jaime",
"title": "I loved it!",
"content": "I loved the wand of ligthning! I usually use it to charge my laptop batteries!",
"rating": 5
}, {
"author": "John Doe",
"title": "Underwhelming",
"content": "I didn't like it at all...",
"rating": 1
}]
}
Now if I try to adapt my code to the sample, I get
undefined is not a function
Here's items.component.ts
import { Component, OnInit } from '#angular/core';
import {ItemsService} from '../items.service';
import {Item} from '../item';
#Component({
selector: 'app-items',
templateUrl: './items.component.html',
styleUrls: ['./items.component.css']
})
export class ItemsComponent implements OnInit {
items: Item[] = [];
errorMessage: string = '';
isLoading: boolean = true;
constructor(private itemsService: ItemsService) { }
ngOnInit() {
this.itemsService
.getAll().
subscribe(
p => this.items =p,
e => this.errorMessage = e,
/* onCompleted */ () => this.isLoading = false
)
}
}
items.service.ts
import { Injectable } from '#angular/core';
import { Http, Response, RequestOptions, Headers } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import {Item} from './item';
#Injectable()
export class ItemsService {
private baseUrl: string ='http://localhost:3000';
constructor(private http: Http) {
}
getAll(): Observable<Item[]>{
let items = this.http
.get(`${this.baseUrl}/articles`, { headers: this.getHeaders()})
.map(this.mapItems)
.catch(this.handleError);
return items;
}
private getHeaders(){
let headers = new Headers();
headers.append('Accept', 'application/json');
return headers;
}
mapItems(response:Response): Item[]{
return response.json().map(this.toItem)
}
toItem(r:any): Item{
let result = <Item>({
id: r.id,
name: r.name,
description: r.description,
price: r.price,
imageUrl: r.imageUrl,
});
console.log('Parsed item:', result);
return result;
}
// this could also be a private method of the component class
handleError (error: any) {
// log error
// could be something more sofisticated
let errorMsg = error.message || `Yikes! There was a problem with our hyperdrive device and we couldn't retrieve your data!`
console.error(errorMsg);
// throw an application level error
return Observable.throw(errorMsg);
}
}
Note: making
return response.json().map(this.toItem)
Into
return response.json()
works. But I would like to get map working.
EDIT: Screenshot
this will solve your issue -
getAll(): Observable<Item[]> {
const items = this.http
.get(`${this.baseUrl}/articles`, {headers: this.getHeaders()})
.map((response: Response) => this.mapItems(response.json()))
.catch(this.handleError);
return items;
}
mapItems(data: Array<any>): Item[] {
return data.map(item => this.toItem(item));
}
I think what you want to map (Array.prototype.map) is the articles in your response object, and not the object itself. Do this:
mapItems(response:Response): Item[]{
return response.json().articles.map(this.toItem)
}