Angular 6: HttpClient Get JSON File 404 Error
Asked Answered
F

3

3

Using the HTTP Client, I'm to retrieve a JSON file which resides the assets directory within my Angular 6 App which was generated using the CLI. While I know there are a couple related questions (and answers) related to this topic, but none have worked in my case.

Below is my file structure:

enter image description here

Specifically I'm trying to retrieve us-all-all.geo.json

angular.json

 "projects": {
    "ng-ngrx-highcharts-example": {
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "prefix": "app",
      "schematics": {},
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/ng-ngrx-highcharts-example",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.app.json",
            "assets": [
              "src",
              "src/assets",
              "src/favicon.ico",
              "src/assets/us-all-all.geo.json"
            ],
            "styles": [
              "src/styles.css"
            ],
            "scripts": []
          },

map-data.service.ts

import { Injectable } from '@angular/core';
import { Observable, of, from } from 'rxjs';
import * as $ from 'jquery';
import { $q } from '@uirouter/angular';

import { catchError, map, tap } from 'rxjs/operators';
import { HttpClient, HttpHeaders } from '@angular/common/http';

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};

@Injectable({
  providedIn: 'root'
})
export class MapDataService {

  mapData: any;

  mapDataObservable: Observable<any>;

  constructor(private http: HttpClient) {
  }

  retrieveNationalMapData(): Observable<any> {
    return this.http.get('./assets/us-all-all.geo.json');

  }
  retrieveNationalCountyMapDataAssets(): Observable<any> {
    return this.http.get('assets/us-all-all.geo.json');
  }

  retrieveNationalCountyMapDataLocalHost(): Observable<any> {
    return this.http.get('http://localhost:4200/assets/us-all-all.geo.json');
  }
}

I call the retrieve function in my component

highchart-map.component.ts

$q.all([
      this.mapDataService.retrieveNationalMapData().subscribe((nationalMapData) => {
        console.log(nationalMapData);
        mapData.national = nationalMapData;
      }),
      this.mapDataService.retrieveNationalCountyMapDataAssets().subscribe((nationalCountyMapData) => {
        console.log(nationalCountyMapData);
        mapData.national = nationalCountyMapData;
      }),
       this.mapDataService.retrieveNationalCountyMapDataLocalHost().subscribe((nationalCountyMapData) => {
        console.log(nationalCountyMapData);
        mapData.national = nationalCountyMapData;
      })

Unfortunately when the app loads I see the following: Console Error Output

So at this point I'm not sure what url I should be using to retrieve the JSON.

EDIT

Link to project of GitHub:ng-ngrx-highcharts-example

Should I be trying retrieve the JSON from the Dist directory?

enter image description here

I see that the JSON files located in src/assets folder are stored in the dist/assets when the app is built.

Final Edit

As stated by user184994, the issue was my use of the HttpClientInMemoryWebApiModule which is intercepting any and all HTTP calls. As a result, I was unable to retrieve my JSON files. After I commented out HttpClientInMemoryWebApiModule my gets were working fine, although it breaks my app which utilizes the inMemoryApi

Furbelow answered 21/6, 2018 at 17:5 Comment(8)
Have you restarted the server (i.e. stop and call ng-serve again) since adding the JSON file?Seed
I restarted the server each time I updated the angular.json file w/ ng serve -o. Also I would delete this dist folder and rebuild using ng buildFurbelow
Strange, I can't reproduce the issue... Is this hosted in GitHub or anything where we can take a closer look and run the code?Seed
return this.http.get('assets/us-all-all.geo.json') should have worked fine. It's strange that it's not working that way. I guess it has to do something with the @uirouter. Put this function in ngOnint and check if you're able to get a response. That way it can be confirmed if @uirouter is involved or notSchlep
Added link to the project Git Repo to original questionFurbelow
@Furbelow If you open localhost:4200/assets/us-all-all.geo.json in your browser, can you see the JSON?Seed
Yes I do, which was one of the first things I looked into when I initially was investigating this issue.Furbelow
@Furbelow Looks like it's to do with your app.module. I've added an answer belowSeed
S
5

The reason is because your app.module is importing HttpClientInMemoryWebApiModule, which intercepts any HTTP calls. Instead of trying to get the JSON from your project, it is instead trying to get it from the InMemoryDataService.

If you remove this import, it should solve the error, although any calls you have that rely on that module will then fail (such as the school, and national requests).

Seed answered 21/6, 2018 at 19:7 Comment(2)
This was the issue! I commented out HttpClientInMemoryWebApiModule and the JSON get requests were working. I'll take another crack at retrieving the JSON from InMemoryDataService but it's currently 24k + lines... Thanks and Accepted Answer!!Furbelow
@Furbelow you can configure it to pass through unknown requests, like this: InMemoryDataService, {dataEncapsulation: false, passThruUnknownUrl: true} , taken from this issue github.com/ngx-translate/core/issues/853Acanthaceous
G
1

That's because you have not defining your path properly since you are in the service folder so you need to change your path {../ which means one step behind}

export class MapDataService {

  mapData: any;

  mapDataObservable: Observable<any>;

  constructor(private http: HttpClient) {
  }

  retrieveNationalMapData(): Observable<any> {
    return this.http.get('../../assets/us-all-all.geo.json');

  }
  retrieveNationalCountyMapDataAssets(): Observable<any> {
    return this.http.get('../../assets/us-all-all.geo.json');
  }

}
Gooding answered 21/6, 2018 at 17:31 Comment(7)
In the 3rd example (retrieveNationalCountyMapDataLocalHost) it's using the absolute url though...Seed
no while web pack bundling the code it will check different pathBeggarweed
You can see in the screenshot that it's clearly calling localhost:4200/assets/us-all-all.geo.jsonSeed
404 means folder or source not foundBeggarweed
@ChellappanV I tried your solution, changing the Url in the Http.Get to this.http.get('../../assets/us-all-all.geo.json');, still 404Furbelow
can you try this one ../../../assetsBeggarweed
Same result unfortunately, but ../../../assets made more sense because the map-data.service is three directories deep.Furbelow
L
1

Several notes...

After running the server, just do a simple thing: copy/paste your resource URL into the browser, like this:

enter image description here

If you see the JSON then everything is fine, it means the problem is with how it is requesting from the Angular app. To understand the issue open Network section (or console) in your browser, most probably the issue is that how you are requesting the file.

For example, this: this.http.get('http://localhost:4200/assets/us-all-all.geo.json');
will most probably be converted to:
http://localhost:4200/http://localhost:4200/assets/us-all-all.geo.json'.

See my point?

Solution is simply to call the resource without http://localshost:4200,
like:
this.http.get('assets/us-all-all.geo.json');

Liaotung answered 22/6, 2018 at 11:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.