2

I've read every other article or post about this I can find. I cannot for the life of me figure out where I'm going wrong with this simple task. (Specifically following this example.) I must be doing something obviously stupid but I've been looking at this so long I can't see it.

I have a json file called isRecognized.json in assets/mockData. I've added the mockData directory to my webpack config file so it's included in the /dist directory. If I go to http:localhost:4200/assets/mockData/isRecognized.json I'm able to see the file, so I know it's available.

However, when I try to retrieve the file using HTTP Client, it throws a 404 no matter what I try.

EDIT: I'm using Webpack, not Angular CLI.

app.component.ts

import { MyService } from './services/my.service';
import { Component, OnInit, Renderer2 } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

/*
* Main app component that houses all views.
*/
@Component({
    selector: 'app-comp',
    templateUrl: './app.component.html'
})

export class AppComponent implements OnInit {

    constructor(
        private route: ActivatedRoute, private service: MyService
    ) {}

    ngOnInit() {
      this.service.isRecognized();
    }

}

my.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

@Injectable()
export class MyService {

  constructor(private http: HttpClient) { }

  isRecognized() {
    this.getJSON('isRecognized').subscribe(data => {
      console.log(data);
    });
  }

  getJSON(fileName): Observable<any> {
    return this.http.get('http://localhost:4200/assets/mockData/' + fileName + '.json');
  }
}

The error I get in the browser console is:

AppComponent_Host.ngfactory.js? [sm]:1 ERROR Error: [object Object]
    at viewWrappedDebugError (core.js:9795)
    at callWithDebugContext (core.js:15101)
    at Object.debugCheckAndUpdateView [as checkAndUpdateView] (core.js:14628)
    at ViewRef_.webpackJsonp../node_modules/@angular/core/esm5/core.js.ViewRef_.detectChanges (core.js:11605)
    at core.js:5913
    at Array.forEach (<anonymous>)
    at ApplicationRef.webpackJsonp../node_modules/@angular/core/esm5/core.js.ApplicationRef.tick (core.js:5913)
    at core.js:5746
    at ZoneDelegate.webpackJsonp../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:391)
    at Object.onInvoke (core.js:4756)

If I debug the error, I can see the body of the error is: enter image description here

Paul Erdos
  • 1,355
  • 2
  • 23
  • 47

4 Answers4

5

I have this working successfully in my app just using a URL like this:

private productUrl = 'api/products/products.json';

Notice that it does not have the localhost part of the path.

So try something more like this:

'assets/mockData/' + fileName + '.json'

Also ensure that your angular.json has the path listed under assets:

        "assets": [
          "src/favicon.ico",
          "src/assets",
          "src/api"
        ],

NOTE: I also didn't do anything to modify my webpack configuration. (But I'm using the CLI.)

If you want to look at some working code that accesses a json file, I have an example here:

https://stackblitz.com/edit/github-gettingstarted-deborahk

DeborahK
  • 57,520
  • 12
  • 104
  • 129
  • I've tried using a local path multiple times with no luck. – Paul Erdos Feb 20 '19 at 16:24
  • Well, she did provide a working example. Maybe you could identify what exactly she did did differently and how she got it to work? – Trevor Feb 20 '19 at 17:05
  • 1
    The Url that you had in your example `assets/products/products.json`, just worked great for me in an ionic project. – dev1998 Apr 03 '19 at 02:27
0

I would suggest subscribing in the component, and returning an Observable from the service:

Service:

@Injectable()
export class MyService {

  constructor(private http: HttpClient) { }

  isRecognized(fileName): Observable<any> {
    return this.http.get('http://localhost:4200/assets/mockData/' + fileName + '.json');
  }

}

Component:

export class AppComponent implements OnInit {

    constructor(
        private route: ActivatedRoute, private service: MyService
    ) {}

    ngOnInit() {
      this.service.isRecognized(fileName)
         .subscribe(data => {
              console.log(data);
         });
    }
}
Stephen R. Smith
  • 3,310
  • 1
  • 25
  • 41
0

While this might not be a direct solution to your specific problem, you should take a look at the npm package json-server. I use it to mock the API when developing and testing the client.

json-server npm

It will run a node web server on port 3000, and is really easy to use right out of the box.

See this tutorial example of how to use it: Mock api with json-server

There might be better examples and setting up the proxy isn't necessary, but should be good enough.

Trevor
  • 481
  • 10
  • 25
0

Finally figured out the answer! I had this in my app.module.ts file as an import:

InMemoryWebApiModule.forRoot(InMemoryDataService, { dataEncapsulation: false })

Removing this fixed the issue immediately.

Paul Erdos
  • 1,355
  • 2
  • 23
  • 47