Can't get data from JSON file - json

I can't get JSON local file Angular HTTP service. I have these codes:
import {Injectable} from '#angular/core';
import {Http, Response} from "#angular/http";
import 'rxjs/add/operator/map'
#Injectable()
export class ApiService {
constructor(private http:Http) {
}
private coinsUrl:string = 'app/data/coins.json';
getMines() {
return this.http.get(this.coinsUrl).subscribe(
(res:Response)=> {
const sss = res.json();
console.log('sss', sss);
}
);
}
}

Since you are using angular-cli that file location will not be available to you at runtime (either using ng serve or a production build). Put the file in the assets folder and then you can load /assets/coins.json.

Related

Get data from a json file into Angular ts

Is there any way to get data from a JSON file to angular typescript file in order to use in web pages?
this.http.get<any>('http://localhost:81/CO226/project/loginResult.json').subscribe((res: Response)=>{
});
this is what I tried.
JSON file could be saved to assets directory inside your project and can be accessed through the following code
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class TempJsonService {
jsonUrl = 'assets/file.json';
constructor(private http: HttpClient) { }
getJson(): Observable<any> {
return this.http.get(this.jsonUrl);
}
}

Angular 7 - Cannot read JSON file from assets

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.

ERROR Could not load Json file: {"headers":{"normalizedNames":{},"lazyUpdate":null} in angular

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

How do you return data to your Angular app using proxy.conf.json?

I am using proxy.conf.json as I develop my Angular application.
However I would like to, for a few endpoints, simply return a JSON object when called. Currently my proxy.conf file redirects to a locally running backend which returns these JSONs. However I'd rather not run the backend server and simply return the JSON from proxy.conf.json.
Is this possible somehow?
It is possible by using proxy.conf.js instead of proxy.conf.json. Then you can specify a bypass function where you can return a response directly. This is mentioned in the angular-cli documentation for the proxy but it does not give many details. Here is a sample proxy.conf.js file to do it.
const PROXY_CONFIG = {
'/api': {
'target': 'http://localhost:5000',
'bypass': function (req, res, proxyOptions) {
switch (req.url) {
case '/api/json1':
const objectToReturn1 = {
value1: 1,
value2: 'value2',
value3: 'value3'
};
res.end(JSON.stringify(objectToReturn1));
return true;
case '/api/json2':
const objectToReturn2 = {
value1: 2,
value2: 'value3',
value3: 'value4'
};
res.end(JSON.stringify(objectToReturn2));
return true;
}
}
}
}
module.exports = PROXY_CONFIG;
You need to recheck the url in the bypass function because it is called for all /api requests and then you just directly return a response for the ones you want the others will still be redirected to the target address. You return true to tell the proxy the request finished.
Make sure to then specify the correct file when running ng serve --proxy-config proxy.conf.js.
For returning JSON from proxy.config.conf, there doesn't seem to be an easy way to do it.
One way would be to have a baseApiUrl in the environment.ts file as well urlSuffix set to .json. Then all of the API calls would have to be something like this: enviroment.baseApiUrl + uri + environment.urlSuffix. Then in environment.prod.ts, the urlSuffix would be an empty string. This is a hacky solution but would work.
Alternative using HTTP_INTERCEPTORS
A cleaner solution that leverages the framework, would be to use an HttpInterceptor with the HttpClient along with setting the baseApiUrl in the environment.ts file. This allows for different API endpoints per environment.
environment.ts
export const environment = {
apiBaseUrl: 'http://localhost:4200/assets/api',
production: false
}
development.interceptor.ts
import {Injectable} from '#angular/core';
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '#angular/common/http';
import {Observable} from 'rxjs/Observable';
import {environment} from '../environments/environment';
#Injectable()
export class DevelopmentInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let clonedRequest = null;
if (!environment.production) {
clonedRequest = request.clone({
url: `${request.url}.json`
});
return next.handle(clonedRequest);
}
return next.handle(clonedRequest);
}
}
This class will intercept any http request made by the HttpClient. Using the properties in the environment.ts file, you can check if the current build is a production build. If it is, clone the request and append .json to it. Anything that is in the assets folder is accessible from the browser. Below is a sample file that maps to the url http:localhost:4200/assets/api/test.json.
/src/assets/api/test.json
{
"name": "test",
"description": "Test Data"
}
Place this file in the assets directory and have the directory structure follow the endpoints of the actual API.
test.service.ts
import {Injectable} from '#angular/core';
import {HttpClient} from '#angular/common/http';
import {Observable} from 'rxjs/Observable';
import {environment} from '../environments/environment';
#Injectable()
export class TestService {
private baseUrl = `${environment.apiBaseUrl}/test`;
constructor(private http: HttpClient) {
}
getTestData(): Observable<any> {
return this.http.get(this.baseUrl);
}
}
Import the environment.ts file here and set the base url to the apiBaseurl property. As long as you import the environment.ts file and not the environment.prod.ts file, this will work in all environments as the appropriate environment file will be read from when the app is built. So this url only has to be change in one place per environment.
Angular CLI Build Targets & Environment Files
app.component.ts
import {Component, OnInit} from '#angular/core';
import {TestService} from './test.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'app';
constructor(private testService: TestService) {
}
ngOnInit() {
this.testService.getTestData().subscribe(
(testData) => console.log(testData)
);
}
}
Here the TestService is injected into the AppComponent and the getTestData() method is called to fetch data from the API. The DevelopmentInterceptor checks the environment and appends .json to the request. Then the data is logged to the console.
app.module.ts
import {BrowserModule} from '#angular/platform-browser';
import {NgModule} from '#angular/core';
import {HTTP_INTERCEPTORS, HttpClientModule} from '#angular/common/http';
import {AppComponent} from './app.component';
import {DevelopmentInterceptor} from './development.interceptor';
import {TestService} from './test.service';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [
TestService,
{
provide: HTTP_INTERCEPTORS,
useClass: DevelopmentInterceptor,
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule {
}
Register the TestService and the DevelopmentInterceptor as providers.
Using this setup, proxy.config.json is not necessary.
For more information on HttpInterceptors, there is the Angular Documentation Intercepting Http Requests & Responses.
There is also a tutorial by Jason Watmore that does some more advanced things with this approach. Angular 5 - Mock Backend Example for Backendless Development

Ionic 2 - Turning HTTP GET JSON Response into an array of items

I am working on an app and am having difficulty using an API call to Eventbrite in a provider, parsing the JSON it returns, and inserting the data I want into an array.
Here is my provider (event-provider.ts):
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import {NativeStorage} from "ionic-native";
import 'rxjs/add/operator/map';
/*
Generated class for the EventProvider provider.
See https://angular.io/docs/ts/latest/guide/dependency-injection.html
for more info on providers and Angular 2 DI.
*/
#Injectable()
export class EventProvider {
constructor(public http: Http) {
console.log("Event Provider")
}
public getJsonData(){
return this.http.get('https://www.eventbriteapi.com/v3/events/search/?location.address=Atlanta&expand=organizer,venue&token=VMGQGYQUIO3IKNS75BD4').map(res => res.json().events);
}
//console.log('Hello EventProvider Provider');
}
And here is the event page in which I eventually will list the data (events.ts):
import { Component } from '#angular/core';
import {EventProvider} from '../../providers/event-provider';
import { NavController } from 'ionic-angular';
#Component({
selector: 'event-list',
templateUrl: 'events.html',
providers: [EventProvider]
})
export class EventsPage {
events = []
constructor(public navCtrl: NavController, private eventProvider: EventProvider) {
this.events = eventProvider.getJsonData();
}
}
For the above .ts file I am getting an error at this.events = eventProvider.getJsonData();. The error says: Type 'Observable' is not assignable to type 'any[]'. Property 'find' is missing in type 'Observable'. I do not really understand this error.
This is what the JSON response looks like: EventBrite
Basically, I want to add each event as an item to an array. The JSON response contains about 500 events.
I've just stuck at the moment an not sure if on on the right track. It is hard to debug my code because it is being tested in an iOS emulator and thus the console.log() doesn't work. Any tips on how to reach my goal of creating an array of events from the JSON response?
You need to subscribe to observables in order to make a request.
this.events = eventProvider.getJsonData();
should be something like:
eventProvider.getJsonData().subscribe((res)=>{
this.events = res.events;
});
And Also you need to return that json and assuming you always have event properties in the response:
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import {NativeStorage} from "ionic-native";
import 'rxjs/add/operator/map';
/*
Generated class for the EventProvider provider.
See https://angular.io/docs/ts/latest/guide/dependency-injection.html
for more info on providers and Angular 2 DI.
*/
#Injectable()
export class EventProvider {
constructor(public http: Http) {
console.log("Event Provider")
}
public getJsonData(){
return this.http.get('yourUrl')
.map(res => {
let body = res.json();
return body.events || { };
});
}
}