Angular 2: Error while accessing JSON from HTTP - json

I am creating an application in angular 2. I am trying to access the json data via http in a service. But i am getting an error saying that
**GET http://localhost:4200/data/products.json 404 (Not Found)**
I have the data in the specified folder but i am unable to access it.
My service code is as follows.
import { Injectable } from '#angular/core';
import { Http, Response } from '#angular/http';
import { Observable } from 'rxjs';
import 'rxjs/add/operator/map';
import { Item } from './item';
#Injectable()
export class ItemService {
observableItems: Observable<Item[]>
allItems: Item[] = [];
selectedItems: Item[] = [];
errorMessage: string;
url = "http://localhost:4200/data/products.json";
constructor(private http:Http) {
this.observableItems = this.http.get(this.url).map((res: Response) => res.json());
this.observableItems.subscribe(
data => this.allItems = data,
error => this.errorMessage = <any>error);
}
getItems(): Observable<Item[]> {
return this.observableItems;
}
getSelectedItems(): Item[] {
return this.selectedItems;
}
addItem(id:number): void {
let item = this.allItems.find(ob => ob.id === id);
if (this.selectedItems.indexOf(item) < 0) {
this.selectedItems.push(item);
}
}
removeItem(id:number): void {
let item = this.selectedItems.find(ob => ob.id === id);
let itemIndex = this.selectedItems.indexOf(item);
this.selectedItems.splice(itemIndex, 1);
}
}

My html files are in
"Project/src/app/..."
So to access JSON File I need to come back from tabs folder and app folder to reach the base directory for both code and images. I used ../ to come back from a folder.
From this my url in the service will be as follows:
url = "../../assets/data/products.json";

Try using direct path to the file from the location of your service file. For example:
url = "data/products.json";
It will work.

Related

Parse a json data from internal json file using Angular throwns error

I tried to get json from tne internal json file within angular.
with this service (village.service):
import { Injectable, OnInit } from '#angular/core';
import { Http, Response } from '#angular/http';
import { environment } from '../../environments/environment';
import { Observable } from 'rxjs'
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
#Injectable()
export class RecordsService {
data: any;
constructor(private http: Http) { }
getVillages(id) {
return this.http.get('../assets/data/villages.json')
.map(data => {
this.data = data.json();
return data.json();
}, err => {
if (err) {
return err.json();
}
});
}
}
and under commponet i put the:
ngOnInit() {
this.getVillages();
....
}
and here to load as the chain dropdown
onSubDistrictSelected(subDistrictId: number) {
if (subDistrictId) {
this.onLoading.emit(true);
this.customer.subDistrict = this.subDistricts.filter(c => (c.id == subDistrictId))[0].name;
this.customer.sdid = subDistrictId;
this.customer.subDistrictId = subDistrictId;
this.villages = this.getVillages().filter((item) => {
return item.subDistrictId === Number(subDistrictId)
});
this.onLoading.emit(false);
}
}
I got error when compile said: this.getVillages is not function, But is working correctly if i put the json value inside the component file:
getVillages() {
return [
{ json_data}
]
}
What I want to achieved is I want to used the JSon file instead put directly inside the commponet.
Thanks,
getVillages is a method in service, so you need to instantiate the service before you use it.
First you need to provide the RecordsService in a module, like,
app.module.ts
...
providers : [
RecordsService
]
...
And in your component,
abc.component.ts
constructor(public recordService : RecordsService) {
}
ngOnInit() {
this.recordService.getVillages();
}
Let me know if you still get the error or have some different error.
EDIT:
getVillages() is returning an Observable, so you need to subscribe in order to use the data returned.
this.recordService.getVillages().subscribe( data => {
console.log(data);
} )

ERROR Could not load Json file: {"headers":{"normalizedNames":{},"lazyUpdate":null} in angular

I have this code to load a json file on a specific api to make login form, after making login structure Iam trying to get data from a specific api, but the problem is not responsing the json file which contain api url:
import {environment} from '../environments/environment';
import {IAppConfig} from './_models/app.config.model';
import {HttpClient} from '#angular/common/http';
import {Injectable} from '#angular/core';
import 'rxjs/add/operator/toPromise';
#Injectable()
export class AppConfig {
static settings: IAppConfig;
constructor(private http: HttpClient) {
}
load() {
const jsonFile = `config/config${environment.production ? '' :
'.dev'}.json`;
return new Promise<void>((resolve, reject) => {
console.log('inside promise');
console.log(jsonFile);
this.http.get<IAppConfig>(jsonFile).toPromise().then((response:
IAppConfig) => {
console.log(response);// here reponse fails
if (!this.isInstanceOfIAppConfig(response)) {
reject(`Could not load file '${jsonFile}': Json format does not
match config`);
}
AppConfig.settings = response;
resolve();
}).catch((response: any) => {
reject(`Could not load file '${jsonFile}':
${JSON.stringify(response)}`);
});
});
}
isInstanceOfIAppConfig(object: any): object is IAppConfig {
console.log(object);
return 'apiBaseUrl' in object;
}
}
For Which config.dev.json file contains the url api:
{
"apiBaseUrl": "https://getDatafromSpecificApi/api/v1"
}

How to get a response body using Observables

I'm using the ng-book as a reference and one of those examples uses observable to get json data but now I want to retrieve data for my own project using a different api which is this http://mindicador.cl/api
but I got an error which is "Return expression type is not assignable to type Observables". How can I solve this? or How can I get json data with observables?
import {
Injectable,
Inject
} from '#angular/core';
import {Observable} from 'rxjs';
import {HttpClient} from '#angular/common/http';
import {Indicadores} from '../indicadores/indicadores.model';
export const MINDICADOR_API = 'http://mindicador.cl/api';
#Injectable()
export class MindicadorService {
constructor(private http: HttpClient, #Inject(MINDICADOR_API) private apiUrl: string) {
}
search(): Observable<Indicadores> {
const queryUrl = this.apiUrl;
return this.http.get(queryUrl)
.subscribe((res) => {
return new Indicadores()
});
}
}
You were try to return from subscribe, which tends to return subscription object.
It seems like you want to return a data Observable<Indicadores> so have <Indicadores> is enough after http.get
search(): Observable<Indicadores> {
const queryUrl = this.apiUrl;
return this.http.get<Indicadores>(queryUrl);
}
You need to return the observable from the service as below:
search(): Observable<Indicadores> {
const queryUrl = this.apiUrl;
return this.http.get(queryUrl)
);
}
And in your controller, use the .subscribe to get the data

localStorage.getItem gives null while I see the item in my storage stack - Angular 4

I use localStorage to store my auth token in it.
After setting item in storage I could not fetch it again! It's while I can see the item in my browser local storage stack.
Also, when I fetch and console the item exactly after set, It's Ok and the console logs my item.
Note:
All my doing is just for user authentications and so on in an Angular 4 SPA. when I want to check my token in a component's constructor, gives me null!
Update:
Here is the code that I use:
in AuthService.ts after getting token:
localStorage.setItem('currentUser', itemData);
and it's the hole AuthService.ts
import {Injectable} from '#angular/core';
import {Http, Response} from '#angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
#Injectable()
export class AuthService {
public token: string;
public userRole: number;
constructor(private http: Http) {
this.initCurrentUser();
}
initCurrentUser() {
const currentUser = JSON.parse(localStorage.getItem('currrentUser'));
this.token = currentUser && currentUser.token;
this.userRole = currentUser && currentUser.role;
}
isAuthenticated(): boolean {
return !!this.token;
}
logout(): void {
this.token = null;
this.userRole = null;
localStorage.removeItem('currentUser');
}
login(email: string, password: string): Observable<boolean> {
return this.http.post('http://localhost:8000/api/login',
{email: email, password: password})
.map((response: Response) => {
try {
let token = response.json() && response.json().token;
if (token) {
this.token = token;
let itemData= JSON.stringify({email: email, token: token});
localStorage.setItem('currentUser', itemData);
return true;
} else {
return false;
}
} catch (e) {
return false;
}
});
}
}
and finally, in HomeComponent.ts, to check authentication:
constructor(private auth: AuthService) {
auth.initCurrentUser();
console.log('Home', auth.token); // That gives me a null!
}
In every authentication check I had checked token that I had in auth service and I think that was the point.
I put the initCurrentUser() method in ngOnInit instead of constructor. and in every authentication checking I fetch the user data from local storage and process some on it to checking user authentication.
So the below is my final code that solved my problem:
ngOnInit() {
let currentUser = JSON.parse(localStorage.getItem('currrentUser'));
if (currentUser) {
this.token = currentUser.token;
this.userRole = currentUser.role;
} else {
console.log('not get on init!');
}
}
isAuthenticated(): boolean {
let data = localStorage.getItem('currentUser');
this.token = JSON.parse(data) && JSON.parse(data).token;
this.userRole = JSON.parse(data) && JSON.parse(data).role;
return !!this.token;
}
In my case, I mistakenly placed the key instead of value. Make sure you pass them in a correct order:
localStorage.setItem('key','value');

How do i handle JSON Data in Angular 2?

Hi I am new to Angular and I have been trying to learn Angular 2 so be gentle :).
I have been trying to use WordPress as my data API using WP API plugin. And have so far been able to get posts from WordPress. And below is my code for the data service.
import {Injectable} from "angular2/core";
import {Http, Response} from 'angular2/http';
import {Observable} from 'rxjs/Rx';
import {PostInterface} from './data.interface';
import {Headers} from "angular2/http";
import {RequestOptions} from "angular2/http";
#Injectable()
export class DataService{
private _dataURL : string = 'http://localhost/wordpress/?rest_route=/wp/v2/posts';
posts : PostInterface [];
post : PostInterface;
errorMessage : string;
constructor(private http:Http){}
getPosts():Observable<any[]>{
//return this.http.get(this._dataURL).map((res:Response) => res.json());
return this.http.get(this._dataURL)
.map(res=>res.json())
//.do(data => console.log(data)) // eyeball results in the console
.catch(this.handleError);
}
//todo fix search
getPost(filterid:number):Observable<any[]>{
//filterid is the id of a specific post
this._dataURL = this._dataURL + '/' + filterid;
return this.http.get(this._dataURL)
.map(res => res.json())
.catch(this.handleError);
}
private handleError (error: Response) {
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
}
In the code I get all the post data using the getPosts() method but I also have a getPost() method to fetch specific post.
I was wondering if I could use the JSON data fetched by getPosts() and use it again in getPost() method. Currently what the getPost() does is call the http.get again I do not want to make http.get request again and again.
I want the getPosts() to make one request, fetch the data and store is somewhere so that other methods can use the data and do their specific manipulations.
Thanks
Yes you can firstly fetch your all data and save into one variable or another methods is where you subscribing your data perform for loop and match with your filterId where the process matches store that data into array and implement your manipulation according to need. here is example assuming your data is in array form..
import {Injectable} from "angular2/core";
import {Http, Response} from 'angular2/http';
import {Observable} from 'rxjs/Rx';
import {PostInterface} from './data.interface';
import {Headers} from "angular2/http";
import {RequestOptions} from "angular2/http";
#Injectable()
export class DataService{
private _dataURL : string = 'http://localhost/wordpress/?rest_route=/wp/v2/posts';
posts : PostInterface [];
post : PostInterface;
errorMessage : string;
constructor(private http:Http){}
getPosts():Observable<any[]>{
//return this.http.get(this._dataURL).map((res:Response) => res.json());
return this.http.get(this._dataURL)
.map(res=>{
if(res.json()){
return res.json()
}
});
//.do(data => console.log(data)) // eyeball results in the console
.catch(this.handleError);
}
// Method in any file where you want to subscribe your data and wanna fetch specific post //
singlePost: Array<any>= [];
methodName(filterid:number){
service.getPosts()
.subscribe(res=>{
console.log(res) // Here you data whihc is coming from .map i.e getPosts methods using Http
for(let i=0; i< res.length ; i++){ // I am asuming your data is in array from so performing length functionality
if(filterid == res[i].filterid){
this.singlePost = res[i];
break;
}
}
console.log(this.singlePost) // This will return your single Specific POst without using `Http` again and again
})
}
You could try something like that using the do operator to save the data into your service when the getPosts result is received:
#Injectable()
export class DataService{
private _dataURL : string = 'http://localhost/wordpress/?rest_route=/wp/v2/posts';
posts : PostInterface [];
post : PostInterface;
errorMessage : string;
constructor(private http:Http){}
getPosts():Observable<any[]>{
//return this.http.get(this._dataURL).map((res:Response) => res.json());
return this.http.get(this._dataURL)
.map(res=>res.json())
.do(data => this.posts = data) // <--------
.catch(this.handleError);
}
findPostById(id) {
if (this.posts != null) {
return this.posts.find(((element, index, array) {
return (element.id = id);
});
} else {
return null;
}
}
getPost(filterid:number):Observable<any[]>{
var post = findPostById(filterid);
if (post != null) { // <--------
return post;
} else {
this._dataURL = this._dataURL + '/' + filterid;
return this.http.get(this._dataURL)
.map(res => res.json())
.catch(this.handleError);
}
}
Feel free to adapt this code to your needs.