使用http.get()从本地文件加载json

时间:2022-06-28 09:47:36

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:

我正在尝试用http.get()加载一个本地json。我尝试了一些东西,我在堆栈上找到的。它看起来像这样:

this is my app.module.ts where I import the HttpModule and the JsonModule from @angular/http:

这是我的app.module。我从@角度/http导入HttpModule和JsonModule:

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():

在我的组件中,我导入Http并从@ angle / Http响应。然后我有一个名为loadNavItems()的函数,在这个函数中,我尝试使用http.get()用相对路径加载json,并使用console.log()打印结果。函数在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:

我的本地json文件是这样的:

[{
        "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:使用http.get()从本地文件加载json

控制台没有错误,我得到如下输出:

In my html template I would like to loop the items like this:

在我的html模板中,我想循环如下:

<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?

编辑相对路径:我的相对路径也有问题,但我确信当我使用../data/navItems.json时,它是正确的。在屏幕截图中,您可以设置nav- compent .component.ts,在这里,我使用json文件中的相对路径来加载json,该文件位于名为data的文件夹中。怎么了,控制台打印了一个404错误,因为它无法从相对路径找到我的json文件?

使用http.get()从本地文件加载json

6 个解决方案

#1


29  

EDIT

编辑

For Angular 5+ only preform steps 1 and 4

对于角5+,只要求第1和第4步


In order to access your file locally in Angular 2+ you should do the following (4 steps):

为了在角度为2+的地方访问你的文件,你应该做以下(4步):

1. Inside your assets folder create a .json file, example: data.json

1。在您的assets文件夹中创建.json文件,例如:data.json

2. Go to your angular.cli.json inside your project and inside the assets array put another object (after the package.json object) like this:

2。去你的angular.cli。在项目内部和资产数组内部放置另一个对象(在包之后)。json对象)是这样的:

{ "glob": "data.json", "input": "./", "output": "./assets/" }

{“水珠”:“数据。json”、“输入”:“。/”、“输出”:“。/资产/ " }

full example from angular.cli.json

完整的示例从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)

记住,数据。json是我们之前在assets文件夹中添加的示例文件(可以任意命名文件)

3. Try to access your file via localhost. It should be visible within this address, http://localhost:your_port/assets/data.json

3所示。尝试通过本地主机访问您的文件。它应该在这个地址中可见,即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之前,请确保您可以通过在浏览器的URL字段中输入它来访问它。

4. Now preform a GET request to retrieve your .json file (you've got your full path .json URL and it should be simple)

4所示。现在,预先形成一个GET请求来检索您的.json文件(您已经获得了完整的路径.json URL,它应该很简单)

 constructor(private http: HttpClient) {}
        // Make the HTTP request:
        this.http.get('http://localhost:your_port/assets/data.json')
                 .subscribe(data => {
                   console.log(data)
                  });

#2


9  

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.

因为this.http。get返回一个可观察的 ,您不想要响应,您想要它的内容。

The console.log shows you an observable, which is correct because navItems contains an Observable<Response>.

控制台。log显示一个可观察的,这是正确的,因为navItems包含一个可观察的

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

这应该可以很好地工作,关于更多信息,请参考HTTP客户端文档

#3


5  

MY OWN SOLUTION

我自己的解决方案

I created a new component called test in this folder:

我在这个文件夹中创建了一个名为test的新组件:

使用http.get()从本地文件加载json

I also created a mock called test.json in the assests folder created by angular cli (important):

我还创建了一个名为test的模拟。由角cli(重要)创建的资产负债表文件夹中的json:

使用http.get()从本地文件加载json

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

在我的组件测试导入的控制器中,遵循这样的rxjs

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:

这很重要,因为您必须从http get调用映射您的响应,这样您就可以获得json并可以在ngFor中循环它。下面是我如何加载模拟数据的代码。我使用http get调用了mock路径this.http.get(“/assets/mock/test/test.json”)。在此之后,我映射响应并订阅它。然后我将它分配给变量项,并在模板中使用ngFor循环它。我还导出了类型。这是我的整个控制器代码:

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:

它能够正常工作!我现在可以在assests文件夹中添加更多的模拟文件,只需更改路径就可以将其作为json。注意,您还必须在控制器中导入HTTP和响应。在app.module中也是一样。ts(主要)是这样的:

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 { }

#4


0  

I you want to put the response of the request in the navItems. Because http.get() return an observable you will have to subscribe to it.

我你想把请求的响应放在navItems中。因为http.get()返回一个可观察的值,所以您必须订阅它。

Look at this example:

看看这个例子:

// version without map
this.http.get("../data/navItems.json")
    .subscribe((success) => {
      this.navItems = success.json();          
    });

// with map
import 'rxjs/add/operator/map'
this.http.get("../data/navItems.json")
    .map((data) => {
      return data.json();
    })
    .subscribe((success) => {
      this.navItems = success;          
    });

#5


0  

I found that the simplest way to achieve this is by adding the file.json under folder: assets.

我发现最简单的实现方法是添加文件。json在文件夹:资产。

No need to edit: .angular-cli.json

无需编辑:.angular .json

Service

@Injectable()
export class DataService {
  getJsonData(): Promise<any[]>{
    return this.http.get<any[]>('http://localhost:4200/assets/data.json').toPromise();
  }
}

Component

private data: any[];

constructor(private dataService: DataService) {}

ngOnInit() {
    data = [];
    this.dataService.getJsonData()
      .then( result => {
        console.log('ALL Data: ', result);
        data = result;
      })
      .catch( error => {
        console.log('Error Getting Data: ', error);
      });
  }

Extra:

Ideally, you only want to have this in a dev environment so to be bulletproof. create a variable on your environment.ts

理想情况下,您只希望在开发环境中使用它,以便防弹。在您的环境中创建一个变量

export const environment = {
  production: false,
  baseAPIUrl: 'http://localhost:4200/assets/data.json'
};

Then replace the URL on the http.get for ${environment.baseAPIUrl}

然后在http上替换URL。得到$ { environment.baseAPIUrl }

And the environment.prod.ts can have the production API URL.

和environment.prod。ts可以有生产API URL。

Hope this helps!

希望这可以帮助!

#6


-3  

try: this.navItems = this.http.get("data/navItems.json");

试题:这个。navitem = this.http.get(“数据/ navItems.json”);

#1


29  

EDIT

编辑

For Angular 5+ only preform steps 1 and 4

对于角5+,只要求第1和第4步


In order to access your file locally in Angular 2+ you should do the following (4 steps):

为了在角度为2+的地方访问你的文件,你应该做以下(4步):

1. Inside your assets folder create a .json file, example: data.json

1。在您的assets文件夹中创建.json文件,例如:data.json

2. Go to your angular.cli.json inside your project and inside the assets array put another object (after the package.json object) like this:

2。去你的angular.cli。在项目内部和资产数组内部放置另一个对象(在包之后)。json对象)是这样的:

{ "glob": "data.json", "input": "./", "output": "./assets/" }

{“水珠”:“数据。json”、“输入”:“。/”、“输出”:“。/资产/ " }

full example from angular.cli.json

完整的示例从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)

记住,数据。json是我们之前在assets文件夹中添加的示例文件(可以任意命名文件)

3. Try to access your file via localhost. It should be visible within this address, http://localhost:your_port/assets/data.json

3所示。尝试通过本地主机访问您的文件。它应该在这个地址中可见,即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之前,请确保您可以通过在浏览器的URL字段中输入它来访问它。

4. Now preform a GET request to retrieve your .json file (you've got your full path .json URL and it should be simple)

4所示。现在,预先形成一个GET请求来检索您的.json文件(您已经获得了完整的路径.json URL,它应该很简单)

 constructor(private http: HttpClient) {}
        // Make the HTTP request:
        this.http.get('http://localhost:your_port/assets/data.json')
                 .subscribe(data => {
                   console.log(data)
                  });

#2


9  

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.

因为this.http。get返回一个可观察的 ,您不想要响应,您想要它的内容。

The console.log shows you an observable, which is correct because navItems contains an Observable<Response>.

控制台。log显示一个可观察的,这是正确的,因为navItems包含一个可观察的

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

这应该可以很好地工作,关于更多信息,请参考HTTP客户端文档

#3


5  

MY OWN SOLUTION

我自己的解决方案

I created a new component called test in this folder:

我在这个文件夹中创建了一个名为test的新组件:

使用http.get()从本地文件加载json

I also created a mock called test.json in the assests folder created by angular cli (important):

我还创建了一个名为test的模拟。由角cli(重要)创建的资产负债表文件夹中的json:

使用http.get()从本地文件加载json

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

在我的组件测试导入的控制器中,遵循这样的rxjs

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:

这很重要,因为您必须从http get调用映射您的响应,这样您就可以获得json并可以在ngFor中循环它。下面是我如何加载模拟数据的代码。我使用http get调用了mock路径this.http.get(“/assets/mock/test/test.json”)。在此之后,我映射响应并订阅它。然后我将它分配给变量项,并在模板中使用ngFor循环它。我还导出了类型。这是我的整个控制器代码:

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:

它能够正常工作!我现在可以在assests文件夹中添加更多的模拟文件,只需更改路径就可以将其作为json。注意,您还必须在控制器中导入HTTP和响应。在app.module中也是一样。ts(主要)是这样的:

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 { }

#4


0  

I you want to put the response of the request in the navItems. Because http.get() return an observable you will have to subscribe to it.

我你想把请求的响应放在navItems中。因为http.get()返回一个可观察的值,所以您必须订阅它。

Look at this example:

看看这个例子:

// version without map
this.http.get("../data/navItems.json")
    .subscribe((success) => {
      this.navItems = success.json();          
    });

// with map
import 'rxjs/add/operator/map'
this.http.get("../data/navItems.json")
    .map((data) => {
      return data.json();
    })
    .subscribe((success) => {
      this.navItems = success;          
    });

#5


0  

I found that the simplest way to achieve this is by adding the file.json under folder: assets.

我发现最简单的实现方法是添加文件。json在文件夹:资产。

No need to edit: .angular-cli.json

无需编辑:.angular .json

Service

@Injectable()
export class DataService {
  getJsonData(): Promise<any[]>{
    return this.http.get<any[]>('http://localhost:4200/assets/data.json').toPromise();
  }
}

Component

private data: any[];

constructor(private dataService: DataService) {}

ngOnInit() {
    data = [];
    this.dataService.getJsonData()
      .then( result => {
        console.log('ALL Data: ', result);
        data = result;
      })
      .catch( error => {
        console.log('Error Getting Data: ', error);
      });
  }

Extra:

Ideally, you only want to have this in a dev environment so to be bulletproof. create a variable on your environment.ts

理想情况下,您只希望在开发环境中使用它,以便防弹。在您的环境中创建一个变量

export const environment = {
  production: false,
  baseAPIUrl: 'http://localhost:4200/assets/data.json'
};

Then replace the URL on the http.get for ${environment.baseAPIUrl}

然后在http上替换URL。得到$ { environment.baseAPIUrl }

And the environment.prod.ts can have the production API URL.

和environment.prod。ts可以有生产API URL。

Hope this helps!

希望这可以帮助!

#6


-3  

try: this.navItems = this.http.get("data/navItems.json");

试题:这个。navitem = this.http.get(“数据/ navItems.json”);