Not able to access JSON data into angular(.ts) file - json

I am trying to implement internationalization for my web application by using ngx-translate . I am able to access JSON data in the HTMl file but not able to access JSON data in the angular(.ts) file. Can anyone suggest me how to access it in .ts file.

You get the input from json files like you call a backend service. The syntax is the same, but if you read from a local json file it is an synchronous call.
// Import HTTP Client
import { HttpClient } from '#angular/common/http';
// Define property
myDataObject: any;
// Dependency Injection
constructor(private http: HttpClient) {}
// Get the data
ngOnInit() {
this.myDataObject = this.http.get<any>("assets/json/data.json")
.map(response => response)
}
Now you can get the properties from you json object like:
this.myDataObject.myProperty

Related

How to use 'require' to import a JSON in NestJS controller?

I'm trying to return a json file as a controller response, but I can't get the content of the json.
import { Controller, Get, Res, HttpStatus, Query } from '#nestjs/common';
import { Response } from 'express';
import * as MOCKED_RESPONSE_TS from './data/payment-method.data'; // this ts file is imported fine
const MOCKED_RESPONSE = require('./data/payment-method-mock'); // this json file is not found
#Controller('commons')
export class CommonController {
#Get('/payment-method')
getPaymentMoethod(#Res() res: Response): any {
res.status(HttpStatus.OK).send(MOCKED_RESPONSE);
}
}
Actually the log returns: Error: Cannot find module './data/payment-method' and the app doesn't compile
I have done this with express (even with typescript) and works fine.
I don't know if i have to setup my project to read jsons (I'm newby on nest). By the moment I have created a typescript file exporting a const with the json content and I called it successfuly
I guess the problem lies in the way you import your .json file (change import instead of const)
Another advice or solution would be to leverage the .json() method of the res object (which is actually the express adapter response object).
Let's try with this code:
Your common.controller.ts file:
import { Controller, Get, Res, HttpStatus, Query } from '#nestjs/common';
import { Response } from 'express';
import * as MOCKED_RESPONSE_TS from './data/payment-method.data'; // this ts file should still be imported fine
import * as MOCKED_RESPONSE from './data/payment-method-mock.json'; // or use const inside the controller function
#Controller('commons')
export class CommonController {
#Get('/payment-method')
getPaymentMoethod(#Res() res: Response): any {
res.status(HttpStatus.OK).json(MOCKED_RESPONSE); // <= this sends response data as json
}
}
Also in your tsconfig.json file, don't forget to add this line:
tsconfig.json
{
"compilerOptions": {
// ... other options
"resolveJsonModule": true, // here is the important line, this will help VSCode to autocomplete and suggest quick-fixes
// ... other options
}
Last thoughts: you could use the sendfile() method of the res object depending on whether you want to send back a json file or the content of your json file.
Let me know if it helps ;)
first make sure you are calling it correctly.
Are you getting any response at all? if not double check your method name since its spelled like this: getPaymentMoethod and it should be this: getPaymentMethod.
Secondly I would recommend requiring outside the method and setting it to a constant.
Lastly try wrapping it in JSON.stringify() to convert the response to a json stringified object

How to parse external JSON file in the .jsx file

I'm new with React and need some one with my json file Parsing problem. I am having a PerfCompare.jsx with a variable needed in the following compare. And i need this var parsing from a external JSON file(trscConfig.JSON). I am using this lines to do. but always get this SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
trscConfig.JSON
{
"server" : "http://myserver.com"
}
PerfCompare.jsx
import React, { Component } from 'react';
import { Form, Input, Button, Radio, Row, Table, Divider, Progress, Alert } from 'antd';
import math from 'mathjs';
import { stringify } from 'qs';
import PerffarmRunJSON from './lib/PerffarmRunJSON';
import JenkinsRunJSON from './lib/JenkinsRunJSON';
import benchmarkVariantsInfo from './lib/benchmarkVariantsInfo';
import './PerfCompare.css';
//import App_DATA from './trscConfig.JSON';
const server_2 = JSON.parse('./trscConfig.JSON').server;
Use fetch():
const response = await fetch('trscConfig.JSON');
const json = await response.json();
const server_2 = json.server;
Or, if your build tool doesn't support await yet:
fetch('trscConfig.JSON')
.then(response => response.json())
.then(json => {
const server_2 = json.server;
});
In either case, downloading the JSON file at runtime will mean the response will not be available immediately. If this is a React component, I suggest doing this in componentDidMount().
Alternatively, if the JSON file is a static asset:
import {server as server_2} from './trscConfig.JSON';
JSON.parse doesn't know how to make HTTP requests/read files - it just parses exactly what you've passed in. In this case, it's failing because it's trying to convert the literal string ./trscConfig.JSON into a JSON object!
There's two ways you could get this working:
Load in the JSON via your module bundler, as you're doing in the commented out line in your code. I believe Webpack (and most others) support this out of the box, but your configuration might have it disabled, intentionally or otherwise. It might also be because you're using uppercase file extensions - try it with a file that has .json in lowercase.
Use XMLHttpRequest, the Fetch API, or a third-party HTTP client library to download the JSON at runtime, and then parse the downloaded text.

Cant fetch data from local json using Angular

I am trying to fetch data from a local json file so that i would manipulate the data in the view (if u choose UnitOne the only 'roles' u can pick are 'role1','role2','role3' etc.)
So i build a sample application just to demonstrate the whole deal.
Basically I'm getting this error message:
Error: Uncaught (in promise): SyntaxError: Unexpected token < in JSON
at position 0 SyntaxError: Unexpected token < in JSON at position 0 at
JSON.parse () at Response.Body.json
here's the code Link
Your http call is not getting the JSON file because it does not live at http://localhost/data.json. That call is returning some HTML, which is why you get the error you get.
You can import the JSON file using TypeScript instead of trying to request it via HTTP.
import { Component, OnInit } from '#angular/core';
import 'rxjs/add/operator/toPromise';
import { Http } from '#angular/http';
import { RootObject, Parameter, Infos, Info, ValidValues, Condition} from './data.model';
import json from './data.json'
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
data: RootObject;
print: string = '';
constructor(private http: Http) { }
ngOnInit() {
this.data = json as RootObject;
this.print = this.data.parameters[1].keyParameterName;
}
}
Here is a working version.
There may be prettier ways to write the code, but I'll leave that up to you. :)
If you absolutely must request the JSON via HTTP, then I recommend you place it in your assets directory and make a call to /assets/data.json instead. That might work. Either that or use a CDN/external URL to request it from. But keep in mind you would need to have CORS enabled on that server or your request will be blocked by your browser.
The only issue here is your json file is not within assets folder.
You should move that file to your assets folder , and then try with the same code , and it will work.
Keep your file in the root of assets , as you are trying to fetch
./data.json ,
if you move to some of folder name asdf within assets , then you
need to change it like ./asdf/data.json

Reading from a non-static JSON file in an Angular4 app

I have a basic Angular web app which reads from a JSON file located on the same server as the app and parses through the JSON file in order to set certain values on objects which drive certain behavior in my app (applies css classes, etc.)
I am not able to find online and/or figure out myself how to set up the controller to read from the JSON file in a way that allows the file to be changed and Angular to dynamically reload the file once it has been changed without reloading the entire page. The JSON file is local on the server where the app is deployed, and I wanted to avoid standing up a web service just to serve a file that already exists on the same server the app is deployed.
Here is what I am doing now:
ngOnInit(): void {
// Make the HTTP request:
this.http.get('../assets/applicationLogs.json').subscribe(data => {
// Read the result field from the JSON response.
this.node_a_status= data.nodes[0].status;
this.node_b_status= data.nodes[1].status;
this.node_c_status= data.nodes[2].status;
});
}
And here is a what my JSON file looks like:
{
"nodes":[
{ "node":"Node A", "status":"processing", "errors":null },
{ "node":"Node B", "status":"processing", "errors":null },
{ "node":"Node C", "status":"inactive", "errors":null }
]
}
First, I know I will probably need to move this get logic out of ngOnInit(), but I am a little lost on how I should go about achieving the desired behavior I have described with typescript.
You're using an http request method on the file so "Poll it"... same way you would any other http JSON service. Here's a ready made poller for you to import: https://www.npmjs.com/package/rx-polling
Best thing you can do is create a service out of it and call it in ngOnInit method and use the response the same way you've shown.
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/dom/ajax';
import 'rxjs/add/operator/map';
import polling from 'rx-polling';
// Example of an Observable which requests some JSON data
const request$ = Observable.ajax({
url: '../assets/applicationLogs.json',
crossDomain: true
}).map(response => response.response || [])
.map(response => response.slice(0, 10)); // Take only first 10 comments
polling(request$, { interval: 5000 }).subscribe((comments) => {
console.log(comments);
}, (error) => {
// The Observable will throw if it's not able to recover after N attempts
// By default it will attempts 9 times with exponential delay between each other.
console.error(error);
});

Loading JSON Without an HTTP Request

I am working on a project using Angular 4, NPM, Node.js, and the Angular CLI.
I have a rather unusual need to load JSON into an Angular service (using an #Injectable) without an HTTP request, i.e. it will always be loaded locally as part of the package, and not retrieved from a server.
Everything I've found so far indicates that you either have to modify the project's typings.d.ts file or use an HTTP request to retrieve it from the /assets folder or similar, neither of which is an option for me.
What I am trying to accomplish is this. Given the following directory structure:
/app
/services
/my-service
/my.service.ts
/myJson.json
I need the my.service.ts service, which is using #Injectable, to load the JSON file myJson.json. For my particular case, there will be multiple JSON files sitting next to the my.service.ts file that will all need to be loaded.
To clarify, the following approaches will not work for me:
Using an HTTP Service to Load JSON File From Assets
URL: https://stackoverflow.com/a/43759870/1096637
Excerpt:
// Get users from the API
return this.http.get('assets/ordersummary.json')//, options)
.map((response: Response) => {
console.log("mock data" + response.json());
return response.json();
}
)
.catch(this.handleError);
Modifying typings.d.ts To Allow Loading JSON Files
URL: https://hackernoon.com/import-json-into-typescript-8d465beded79
Excerpt:
Solution: Using Wildcard Module Name
In TypeScript version 2 +, we can use wildcard character in module name. In your TS definition file, e.g. typings.d.ts, you can add this line:
declare module "*.json" {
const value: any;
export default value;
}
Then, your code will work like charm!
// TypeScript
// app.ts
import * as data from './example.json';
const word = (<any>data).name;
console.log(word); // output 'testing'
The Question
Does anyone else have any ideas for getting these files loaded into my service without the need for either of these approaches?
You will get an error if you call json directly, but a simple workaround is to declare typings for all json files.
typings.d.ts
declare module "*.json" {
const value: any;
export default value;
}
comp.ts
import * as data from './data.json';
The solution I found to this was using RequireJS, which was available to me via the Angular CLI framework.
I had to declare require as a variable globally:
declare var require: any;
And then I could use require.context to get all of the files in a folder I created to hold on the types at ../types.
Please find below the entire completed service that loads all of the JSON files (each of which is a type) into the service variable types.
The result is an object of types, where the key for the type is the file name, and the related value is the JSON from the file.
Example Result loading files type1.json, type2.json, and type3.json from the folder ../types:
{
type1: {
class: "myClass1",
property1: "myProperty1"
},
type2: {
class: "myClass2",
property1: "myProperty2"
},
type3: {
class: "myClass3",
property1: "myProperty3"
}
}
The Final Service File
import { Injectable } from '#angular/core';
declare var require: any;
#Injectable()
export class TypeService {
constructor(){
this.init()
};
types: any;
init: Function = () => {
// Get all of the types of branding available in the types folder
this.types = (context => {
// Get the keys from the context returned by require
let keys = context.keys();
// Get the values from the context using the keys
let values = keys.map(context);
// Reduce the keys array to create the types object
return keys.reduce(
(types, key, i) => {
// Update the key name by removing "./" from the begining and ".json" from the end.
key = key.replace(/^\.\/([^\.]+)\.json/, (a, b)=> { return b; });
// Set the object to the types array using the new key and the value at the current index
types[key] = values[i].data;
// Return the new types array
return types;
}, {}
);
})(require.context('../types', true, /.json/));
}
}
You can directly access variables in services from their object that is defined in the constructor.
...So say your constructor loads the service like this
constructor(private someService:SomeService){}
You can just do someService.theJsonObject to access it.
Just be careful not to do this before it gets loaded by the service function that loads it. You'd then get a null value.
You can assign variables to your service files the same way you do in component files.
Just declare them in the service
public JsonObject:any;
And (easiest way) is to let the function that called your service assign the JSON object for you.
So say you called the service like this
this.serviceObject.function().subscribe
(
resp =>
{
this.serviceObject.JsonObject = resp;
}
);
After this is done once, other components can access that JSON content using someService.theJsonObject as discussed earlier.
In your case I think all you need to do is embed your JSON object in your code. Maybe you can use const. That's not bad code or anything.