Load json from local file with http.get() in angular 2
For Angular 5+ only preform steps 1 and 4
In order to access your file locally in Angular 2+ you should do the following (4 steps):
[1] Inside your assets folder create a .json file, example: data.json
[2] Go to your angular.cli.json (angular.json in Angular 6+) inside your project and inside the assets array put another object (after the package.json object) like this:
{ "glob": "data.json", "input": "./", "output": "./assets/" }
full example from angular.cli.json
"apps": [ { "root": "src", "outDir": "dist", "assets": [ "assets", "favicon.ico", { "glob": "package.json", "input": "../", "output": "./assets/" }, { "glob": "data.json", "input": "./", "output": "./assets/" } ],
Remember, data.json is just the example file we've previously added in the assets folder (you can name your file whatever you want to)
[3] Try to access your file via localhost. It should be visible within this address, http://localhost:your_port/assets/data.json
If it's not visible then you've done something incorrectly. Make sure you can access it by typing it in the URL field in your browser before proceeding to step #4.
[4] Now preform a GET request to retrieve your .json file (you've got your full path .json URL and it should be simple)
constructor(private http: HttpClient) {} // Make the HTTP request: this.http.get('http://localhost:port/assets/data.json') .subscribe(data => console.log(data));
You have to change
loadNavItems() { this.navItems = this.http.get("../data/navItems.json"); console.log(this.navItems); }
for
loadNavItems() { this.navItems = this.http.get("../data/navItems.json") .map(res => res.json()) .do(data => console.log(data)); //This is optional, you can remove the last line // if you don't want to log loaded json in // console. }
Because this.http.get
returns an Observable<Response>
and you don't want the response, you want its content.
The console.log
shows you an observable, which is correct because navItems contains an Observable<Response>
.
In order to get data properly in your template, you should use async
pipe.
<app-nav-item-comp *ngFor="let item of navItems | async" [item]="item"></app-nav-item-comp>
This should work well, for more informations, please refer to HTTP Client documentation
MY OWN SOLUTION
I created a new component
called test
in this folder:
I also created a mock called test.json
in the assests
folder created by angular cli
(important):
This mock looks like this:
[ { "id": 1, "name": "Item 1" }, { "id": 2, "name": "Item 2" }, { "id": 3, "name": "Item 3" }]
In the controller of my component test
import
follow rxjs
like this
import 'rxjs/add/operator/map'
This is important, because you have to map
your response
from the http get
call, so you get a json
and can loop it in your ngFor
. Here is my code how I load the mock data. I used http
get
and called my path to the mock with this path this.http.get("/assets/mock/test/test.json")
. After this i map
the response and subscribe
it. Then I assign it to my variable items
and loop it with ngFor
in my template
. I also export the type. Here is my whole controller code:
import { Component, OnInit } from "@angular/core";import { Http, Response } from "@angular/http";import 'rxjs/add/operator/map'export type Item = { id: number, name: string };@Component({ selector: "test", templateUrl: "./test.component.html", styleUrls: ["./test.component.scss"]})export class TestComponent implements OnInit { items: Array<Item>; constructor(private http: Http) {} ngOnInit() { this.http .get("/assets/mock/test/test.json") .map(data => data.json() as Array<Item>) .subscribe(data => { this.items = data; console.log(data); }); }}
And my loop in it's template
:
<div *ngFor="let item of items"> {{item.name}}</div>
It works as expected! I can now add more mock files in the assests folder and just change the path to get it as json
. Notice that you have also to import the HTTP
and Response
in your controller. The same in you app.module.ts (main) like this:
import { BrowserModule } from '@angular/platform-browser';import { NgModule } from '@angular/core';import { HttpModule, JsonpModule } from '@angular/http';import { AppComponent } from './app.component';import { TestComponent } from './components/molecules/test/test.component';@NgModule({ declarations: [ AppComponent, TestComponent ], imports: [ BrowserModule, HttpModule, JsonpModule ], providers: [], bootstrap: [AppComponent]})export class AppModule { }