1

I would like to specify a local path to a JSON file as an attribute in HTML, similar to the src property of an HTML img.

Ideally, something like this:

<my-component data-source="localPath">

where localPath corresponds to the path of a local JSON file that contains the data that will be used to populate the my-component. This way I can use the same component multiple times in my HTML, but just change which JSON file each instance reads from for populating data.

For a single instance, I know the following works (inside of my-component.component.ts):

import myData from 'localPath';
let content = myData.data as MyInterface;

This is from an earlier question I posted about reading JSON files in Angular 12. The issue here, of course, being that all instances of my-component would be stuck using the same JSON file located at localPath.

I suspect that creating a service to "load" the file, much the same way you might read an external URL/API would work... but is there a simpler way? I am just trying to read a local file, not data from an external URL.

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})

export class MyService {

  constructor(public http: HttpClient) { }

  getData(url: string): Observable<Record<string, any>> {
    return this.http.get(url)
      .pipe(map((res) => {
        return res;
      }))
  }
}

The above example is based on this blog post, with the fix mentioned in my earlier post.

Example ideal usage for what I want:

<div>
    <my-component data-source="./localPath/data1.json" />
    <my-component data-source="./localPath/data2.json" />
</div>

Where data1.json and data2.json are two different files to be used as data sources respectively.

  • 2
    well yeah, you have to make a http request for that :) so definitely the service call is required. Think about that as about any other file - when you load main.js in the browser, or load any other lazy-loaded Angular module, you need to "download" it - check the network tab in devtools - you will see no matter what files we are using in the app (js, json, images) they are all fetched using http GET, no matter if they are external or internal – Maciej Wojcik Aug 05 '22 at 21:25

1 Answers1

0

I am just trying to read a local file

This statement is misleading: "local"? All your data and code comes from http. Lets say you end with one js file (+some css and index.html) and u want to add some json file: you either add that json to js file OR you load it in additional http request.

Look 3 ways to load json file: https://stackblitz.com/edit/angular-read-local-json-file?file=src%2Fapp%2Fapp.component.html

2nd and 3rd ways uses http to get json content.

1st one, Typescript import (your way) includes json file in one of loaded files, there is no json file itself on server in this scenario.

So if you want to use your way of reading json file you need to include it into your app source code, so u MUST import all that files in some place, e.g. you can do it in some service:

import myData1 from 'localPath1';
import myData2 from 'localPath2';
...

class JsonHolderService {
   store = {};
   constructor() {
      this.store['localPath1'] = myData1;
      this.store['localPath2'] = myData2;
      ...
   }
}

And then get this data in components.

Petr Averyanov
  • 9,327
  • 3
  • 20
  • 38