I'm trying to load a local json with http.get()
in angular 2. I tried something, that I found here on stack. It looks like this:
this is my app.module.ts
where I import
the HttpModule
and the JsonModule
from @angular/http
:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule, JsonpModule } from '@angular/http';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { NavCompComponent } from './nav-comp/nav-comp.component';
import { NavItemCompComponent } from './nav-comp/nav-item-comp/nav-item-comp.component';
@NgModule({
declarations: [
AppComponent,
NavCompComponent,
NavItemCompComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
JsonpModule,
RouterModule.forRoot(appRoutes)
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
In my component I import
Http
and Response
from @angular/http
. Then I have a function called loadNavItems()
, where I try to load my json with relative path using http.get()
and print the result with console.log()
. The function is called in ngOnInit()
:
import { Component, OnInit } from '@angular/core';
import { Http, Response } from '@angular/http';
@Component({
selector: 'app-nav-comp',
templateUrl: './nav-comp.component.html',
styleUrls: ['./nav-comp.component.scss']
})
export class NavCompComponent implements OnInit {
navItems: any;
constructor(private http: Http) { }
ngOnInit() {
this.loadNavItems();
}
loadNavItems() {
this.navItems = this.http.get("../data/navItems.json");
console.log(this.navItems);
}
}
My local json file looks like this:
[{
"id": 1,
"name": "Home",
"routerLink": "/home-comp"
},
{
"id": 2,
"name": "Über uns",
"routerLink": "/about-us-comp"
},
{
"id": 3,
"name": "Events",
"routerLink": "/events-comp"
},
{
"id": 4,
"name": "Galerie",
"routerLink": "/galery-comp"
},
{
"id": 5,
"name": "Sponsoren",
"routerLink": "/sponsoring-comp"
},
{
"id": 6,
"name": "Kontakt",
"routerLink": "/contact-comp"
}
]
There are no errors in the console, I just get this output:
In my html template I would like to loop the items like this:
<app-nav-item-comp *ngFor="let item of navItems" [item]="item"></app-nav-item-comp>
I made this with a solution I found here on stack, but I have no idea why it doesn't work?
EDIT RELATIVE PATH:
I also get a problem with my relative path, but I'm sure it's the right one when I use ../data/navItems.json
. In the screenshot you can se the nav-comp.component.ts, where I load the json using relative path from the json file which is in the folder called data? What's wrong, the console prints an 404 error, because it can't find my json file from the relative path?
I found that the simplest way to achieve this is by adding the file.json under folder: assets.
No need to edit:
.angular-cli.json
Service
Component
Extra:
Ideally, you only want to have this in a dev environment so to be bulletproof. create a variable on your
environment.ts
Then replace the URL on the http.get for
${environment.baseAPIUrl}
And the
environment.prod.ts
can have the production API URL.Hope this helps!
MY OWN SOLUTION
I created a new
component
calledtest
in this folder:I also created a mock called
test.json
in theassests
folder created byangular cli
(important):This mock looks like this:
In the controller of my component
test
import
followrxjs
like thisThis is important, because you have to
map
yourresponse
from thehttp get
call, so you get ajson
and can loop it in yourngFor
. Here is my code how I load the mock data. I usedhttp
get
and called my path to the mock with this paththis.http.get("/assets/mock/test/test.json")
. After this imap
the response andsubscribe
it. Then I assign it to my variableitems
and loop it withngFor
in mytemplate
. I also export the type. Here is my whole controller code:And my loop in it's
template
: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 theHTTP
andResponse
in your controller. The same in you app.module.ts (main) like this:You have to change
for
Because
this.http.get
returns anObservable<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 anObservable<Response>
.In order to get data properly in your template, you should use
async
pipe.This should work well, for more informations, please refer to HTTP Client documentation
EDIT
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
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 than 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)
I you want to put the response of the request in the
navItems
. Becausehttp.get()
return an observable you will have to subscribe to it.Look at this example:
try:
this.navItems = this.http.get("data/navItems.json");