Im trying to reading a JSON config file from my assets in angular project. I have created a Service and calling in App.Module.ts in a initializeApp function.
my jSON files are in src/assets/config/ folder
When it starts it shows me in console a Empty Json file "{}".
This is my service.
import { IConfig } from "../_model/config";
import { Injectable } from '#angular/core';
import { environment } from 'src/environments/environment';
import { HttpClient, HttpResponse } from '#angular/common/http';
import { Observable } from 'rxjs';
import 'rxjs/add/operator/map';
#Injectable()
export class Config {
static settings: IConfig;
constructor(private http: HttpClient) {
}
load() {
const jsonFile = `assets/config/config.${environment.name}.json`; // ${environment.name} could be 'prod' or 'dev'
return new Promise<void>((resolve, reject) => {
this.http.get(jsonFile).toPromise().then((response: IConfig) => {
Config.settings = <IConfig>response;
resolve();
}).catch((response: any) => {
reject(`Error en archivo de configuracion '${jsonFile}': ${JSON.stringify(response)}`);
});
});
}
and Config interface if you want check:
export interface IConfig {
config: {
production: boolean;
};
path: {
url_root: string;
};
timeZone: {
time: number;
};
}
console error
core.js:15724 ERROR Error en archivo de configuracion 'assets/config/config.dev.json': {}
it always goes for Catch and prints error message with anf EMPTY JSON, like if not exists.
If you need more info just tell me.
I think you have to add the "src/assets/config/" path to the assets: [] array your angular.json file. Then I think you have to recompile the server.
You need to step back twice. ../../
replace
const jsonFile = `assets/config/config.${environment.name}.json`;
with
const jsonFile = `../../assets/config/config.${environment.name}.json`;
Secure Recommention
However, I recommend that you have to place the config inside the environment files instead of the assets folder because the environment is secured by the browsers while assets will be public to anyone.
I have this code to load a json file on a specific api to make login form, after making login structure Iam trying to get data from a specific api, but the problem is not responsing the json file which contain api url:
import {environment} from '../environments/environment';
import {IAppConfig} from './_models/app.config.model';
import {HttpClient} from '#angular/common/http';
import {Injectable} from '#angular/core';
import 'rxjs/add/operator/toPromise';
#Injectable()
export class AppConfig {
static settings: IAppConfig;
constructor(private http: HttpClient) {
}
load() {
const jsonFile = `config/config${environment.production ? '' :
'.dev'}.json`;
return new Promise<void>((resolve, reject) => {
console.log('inside promise');
console.log(jsonFile);
this.http.get<IAppConfig>(jsonFile).toPromise().then((response:
IAppConfig) => {
console.log(response);// here reponse fails
if (!this.isInstanceOfIAppConfig(response)) {
reject(`Could not load file '${jsonFile}': Json format does not
match config`);
}
AppConfig.settings = response;
resolve();
}).catch((response: any) => {
reject(`Could not load file '${jsonFile}':
${JSON.stringify(response)}`);
});
});
}
isInstanceOfIAppConfig(object: any): object is IAppConfig {
console.log(object);
return 'apiBaseUrl' in object;
}
}
For Which config.dev.json file contains the url api:
{
"apiBaseUrl": "https://getDatafromSpecificApi/api/v1"
}
I'm having a tough time understanding how to access different aspects of an JSON object in Angular2. Particularly, I have a web API that I built that returns the following JSON object regarding the hard drive details on my server:
The image is a screenshot of my console in Chrome after using an httpService and Observable to push it to the console but understanding how to get to a specific piece of info is getting lost on me.
If someone could point me in the right direction, it would be greatly appreciated.
After having subscribed to the http Observable you have already got the actual object.
Assuming your http get request looks like this:
this.httpService.get(this.apiUrl);
you can use the power of rxjs Observables, for example map over the object like this:
this.httpService.get(this.apiUrl)
.map(res => res.json())
.map(body => body.Data)
.map(data => data[0].AvailableSpace)
which after subscribing to would return the AvailableSpace.
.subscribe(availablespace => console.log(availablespace);
Watch out for accessing arrays like this, this is just to give you an example on how to access and manipulate objects in observables.
Check this site out for more information on different observable
operators, other than map.
https://www.learnrxjs.io/
Let me try my luck. Hope it will help people understand better. Particularly, I will talk about how to perform get request in Angular 2. It is always better to have a get and post request in a separate file called service.ts as mentioned in the official documentation.
We will have three files, namely example.component.ts, example.service.ts and Model file examplemodel.ts
example.component.ts
import {OnInit, Component} from "#angular/core";
import {ExampleService} from "./example.service"; // import service
import {ResponseFromGet, ErrorMessage} from "./examplemodel"; // import your model
#Component({
providers: [ExampleService], // add your service here in order to use in component file
templateUrl: './example.template.html'
})
export class ExampleComponent implements OnInit{
//Specify Url for Get request
Private _getRequestUrl = "http://entergetrequesturlhere";
// Make variable for stroing get method reponse which can be used in ur template file
responseFromGetMethod: ResponseFromGet; // this can be ur model file which represnts ur JSON model
// For storing Error
errorMessage: ErrorMessage;
//use Constructor to inject your service in component file
constructor(private _exampleService: ExampleService){}
// Since we implemented OnInit we need to override its method ngOnInit
// this method is called when page is loaded
ngOnInit(): any{
this.callGetMethod(this._getRequestUrl);
}
// callGetMethod outside OnInit but inside class ExampleComponent
callGetMethod(getUrl: string){
this._exampleService.getMethodName(getUrl)
.subscribe(
responseFromGetMethod => {
this.responseFromGetMethod = responseFromGetMethod; // Store response from getmethod in your local variable
},
error => this.errorMessage = <any>error // Store error message receiver from server
);
}
}
example.service.ts
import {Http, Response} from "#angular/http";
import {Injectable} from "#angular/core";
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import {ResponseFromGet} from "./examplemodel";
#Injectable()
export class ExampleService{
constructor(private _http: Http) { }
// GET request To access data and specify observable type from model
getMethodName(getUrl): Observable<ResponseFromGet>{
return this._http.get(getUrl)
.map(this.extractData) // to check for the status code
.catch(this.handleError); // to check error
}
// Extracts from response
private extractData(res: Response) {
if (res.status < 200 || res.status >= 300) {
throw new Error('Bad response status: ' + res.status);
}
let response = res.json();
return response || {};
}
// To handle Error
private handleError(error: Response) {
console.error(error);
return Observable.throw(error.json() || 'Server error');
}
}
examplemodel.ts
export interface ResponseFromGet{
id: number;
name: string;
}
export interface ErrorMessage{
message: string;
}
And finally the HTML file
example.template.html
<div>
<h2>{{responseFromGetMethod?.name}}</h2> // this will print the name from the json file
<h3>{{errorMessage?.message}}</h3> // this will print the error if any
</div>
Lastly, this is the model of my JSON file
{
"id": 789;
"name": "Angular2";
}
as I am new to the Angular, can anyone please give a simple solution on loading the JSON file data using angular 2.
My code is like below
Index.html
<html>
<head>
<title>Angular 2 QuickStart</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/styles.css">
<!-- 1. Load libraries -->
<!-- Polyfill(s) for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<!-- 2. Configure SystemJS -->
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
</head>
<!-- 3. Display the application -->
<body>
<my-app>Loading...</my-app>
</body>
</html>
app.component.ts
import {Component} from '#angular/core';
#Component({
selector: 'my-app',
template: `
<div id="main">
Main Div
<div id = "header"></div>
<div id = "content">
<ul class="games">
<li>
</li>
</ul>
</div>
</div>
`
})
export class AppComponent {
}
games.json
{
"games":[
{
"title":"Primary Operations",
"enabled":true
},
{
"title":"Curated Games",
"enabled":false
}
]
}
I want to fetch all games from games.json into li at app.component.ts
Please advise in detail.
Here is a part of my code that parse JSON, it may be helpful for you:
import { Component, Input } from '#angular/core';
import { Injectable } from '#angular/core';
import { Http, Response, Headers, RequestOptions } from '#angular/http';
import {Observable} from 'rxjs/Rx';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
#Injectable()
export class AppServices{
constructor(private http: Http) {
var obj;
this.getJSON().subscribe(data => obj=data, error => console.log(error));
}
public getJSON(): Observable<any> {
return this.http.get("./file.json")
.map((res:any) => res.json())
.catch((error:any) => console.log(error));
}
}
Keep the json file in Assets (parallel to app dir) directory
Note that if you would have generated with ng new YourAppname- this assets directory exists same line with 'app' directory, and services should be child directory of app directory. May look like as below:
::app/services/myservice.ts
getOrderSummary(): Observable {
// get users from api
return this.http.get('assets/ordersummary.json')//, options)
.map((response: Response) => {
console.log("mock data" + response.json());
return response.json();
}
)
.catch(this.handleError);
}
If you using angular-cli Keep the json file inside Assets folder (parallel to app dir) directory
return this.http.get('<json file path inside assets folder>.json'))
.map((response: Response) => {
console.log("mock data" + response.json());
return response.json();
}
)
.catch(this.handleError);
}
Note: here you only need to give path inside assets folder like assets/json/oldjson.json then you need to write path like /json/oldjson.json
If you using webpack then you need to follow above same structure inside public folder its similar like assets folder.
In Angular 5
you can just say
this.http.get<Example>('assets/example.json')
This will give you Observable<Example>
You don't need HttpClient, you don't even need Angular. All you need is WebPack and JSON-Loader, both are already part of Angular-CLI.
All the code you need is this line:
import * as someName from './somePath/someFile.json;
And the your json-data can be found under someName.default. However this code will throw a type-error from the TypeScript compiler - this isn't a real error, but only a type-error.
To solve it add this code to your src/typings.d.ts file (if it doesn't exist create it):
declare module "*.json"
{
const value: any;
export default value;
}
Please notice: that working in this method will compile your json (minify/uglify) into the app bundle at build time. This mean that you won't need to wait until this file will load - as you will if you choice to work with httpClient.get(...) - meaning faster application!
You need to make an HTTP call to your games.json to retrieve it.
Something like:
this.http.get(./app/resources/games.json).map
i think the assets folder is public, you can access it directly on the browser
http://localhost:4020/assets/
unlike other privates folders, drop your json file in the assets folder
I needed to load the settings file synchronously, and this was my solution:
export function InitConfig(config: AppConfig) { return () => config.load(); }
import { Injectable } from '#angular/core';
#Injectable()
export class AppConfig {
Settings: ISettings;
constructor() { }
load() {
return new Promise((resolve) => {
this.Settings = this.httpGet('assets/clientsettings.json');
resolve(true);
});
}
httpGet(theUrl): ISettings {
const xmlHttp = new XMLHttpRequest();
xmlHttp.open( 'GET', theUrl, false ); // false for synchronous request
xmlHttp.send( null );
return JSON.parse(xmlHttp.responseText);
}
}
This is then provided as a app_initializer which is loaded before the rest of the application.
app.module.ts
{
provide: APP_INITIALIZER,
useFactory: InitConfig,
deps: [AppConfig],
multi: true
},
service.service.ts
--------------------------------------------------------------
import { Injectable } from '#angular/core';
import { Http,Response} from '#angular/http';
import { Observable } from 'rxjs';
import 'rxjs/add/operator/map';
#Injectable({
providedIn: 'root'
})
export class ServiceService {
private url="some URL";
constructor(private http:Http) { }
//getData() is a method to fetch the data from web api or json file
getData(){
getData(){
return this.http.get(this.url)
.map((response:Response)=>response.json())
}
}
}
display.component.ts
--------------------------------------------
//In this component get the data using suscribe() and store it in local object as dataObject and display the data in display.component.html like {{dataObject .propertyName}}.
import { Component, OnInit } from '#angular/core';
import { ServiceService } from 'src/app/service.service';
#Component({
selector: 'app-display',
templateUrl: './display.component.html',
styleUrls: ['./display.component.css']
})
export class DisplayComponent implements OnInit {
dataObject :any={};
constructor(private service:ServiceService) { }
ngOnInit() {
this.service.getData()
.subscribe(resData=>this.dataObject =resData)
}
}
For example, in your component before you declare your #Component
const en = require('../assets/en.json');
public init() {
return from(
fetch("assets/server-config.json").then(response => {
return response.json();
})
)
.pipe(
map(config => {
return config;
})
)
.toPromise();
}
Working on a project where the entity gets updated frequently in the database and the ui which is html5 will be displayed using rxjs via rest service.
html5->rxjs->restservice->db
Can someone has experience similar or achieved this ?
My Controller looks like this
import {Component} from 'angular2/core';
import {HomeService} from './home.services';
import {Index} from './index';
#Component({
selector: 'home-app',
providers: [HomeService],
templateUrl: 'MktHome.html',
})
export class HomeComponent {
private indexes: Observable<Index[]>;
constructor(private _service: HomeService){
_service.getIndexes().subscribe(
res => this.indexes = res,
error => alert(" Error is : " + error),
()=> console.log("finished")
);
console.log(this.indexes);
}
generateArray(obj){
return Object.keys(obj).map((key)=>{ return obj[key]});
}
}
Service
import {Injectable, Inject} from 'angular2/core';
import {Http, Response, RequestOptions, Headers, Request, RequestMethod} from 'angular2/http'
import 'rxjs/add/operator/map';
#Injectable()
export class HomeService {
private actionUrl: string;
private headers: Headers;
private requestoptions;
constructor(private _http: Http) {
console.log('Task Service created.', this._http);
this.actionUrl = "http://localhost:8080/index/home";
this.headers = new Headers();
this.headers.append('Content-Type', 'application/json');
this.headers.append("Accept", 'application/json');
}
// Uses http.get() to load a single JSON file
getIndexes(){
this.requestoptions = new RequestOptions({
method: RequestMethod.Get,
url: this.actionUrl,
headers: this.headers})
return this._http.request(new Request(this.requestoptions)).map(res => res.json());
}
}
Thanks
Rafi