could not find module in loading a json into component in angular4 - json

I am using angular4, in a simple component I am trying to load a json, the json and component are on the same path/folder.
import metacoin_artifacts from './MetaCoin.json';
I also tried
import metacoin_artifacts from 'MetaCoin.json';
all of them throw me a error Cannot find module './MetaCoin.json'.
The first approach used to work on one project before, but now it can't work anymore, I don't know what is the difference between them.

Json is not a module, you cannot load json file as above, you can do it as,
public getJSON(): Observable<any> {
return this.http.get("./MetaCoin.json")
.map((res:any) => res.json())
.catch((error:any) => console.log(error));
}

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.

Add information to List in Angular

I'm learning Angular 6 and I have a List shown on my site. Now, i need to give Users of my site the possibility to add entries to that list. There's a form with 4 fields and a submit button, when Submit is clicked, the values should be stored anywhere and all the entries should be shown on the site, permanently, not just in the active session.
How can i achieve this? Do i need to include some sort of database? Or is it possible to append the new dataset to a JSON file?
Thank you in advance
EDIT: This is a training project and will only be available through the Intranet of the Company i work at, so security concerns about missing Captchas or similar things are not a factor
If you are going to use this project for long time and if number of entries is higher and you have alot of users, then you should use some data base. And if there is limited number of users and you need this app temporary then using json file is also good. Using json file will save you from database logics etc if you are not familiar with them
To SAVE some data anywhere you HAVE TO use some kind of database.
Angular is JavaScript framework. It helps to write applications. But it does nothing with server side (except, of course, CLI and other stuff which NodeJS people likes to do).
JSON is not the only way to communicate between browser and the server. But in Angular it's easiest way.
You'll need something on the server (I suppose PHP script) which will receives data from your Angular app and will send back some feedback. In the case with PHP you'd learn how to receive JSON POST ($_POST and $_REQUEST will not work)
What I advise you in terms "how to learn Angular" is go to this step-by-step tutorial https://angular.io/tutorial
Run it twice or three times and you'll understand how works Promises, Observables, communications, templates, services and all other stuff.
It is possible to append the data to the new dataset to the JSON file create a service to read that JSON file using that service so to give you the basics of reading that JSON file
Config.service.ts
#Injectable()
export class ConfigService {
private static _config: any = {}
constructor(private _http: Http) { }
load() {
return new Promise((resolve, reject) => {
this._http.get('../assets/' + 'data.json')
.map(res => res.json())
.subscribe((data) => {
console.log("inside http get of the new service");
console.log(data);
ConfigService._config = data;
resolve(true);
},
(error: any) => {
console.error(error);
return Observable.throw(error.json().error || 'Server error');
});
});
}
// Gets a value of specified property in the configuration file
get(key: any) {
console.log("tell me the base :" + ConfigService._config['BASE_URL']);
return ConfigService._config[key];
}
}
export function ConfigFactory(config: ConfigService) {
return () => config.load();
}
export function init() {
return {
provide: APP_INITIALIZER,
useFactory: ConfigFactory,
deps: [ConfigService],
multi: true
}
}
const ConfigModule = {
init: init
}
export { ConfigModule };
add these lines in your main module
app.module.ts
import { CommonModule } from '#angular/common';
import { ConfigModule, ConfigService } from './config-service';
providers:[
ConfigService,
ConfigModule.init(),
]
Then, you can inject this service on any component or service that wants the data
Also, you have to add an assets folder under your app folder and place the data.json there.

Accessing state in React render method after API request

I'm working on my first complicated React app and I am making a request to a movie API. My site allows the user to do a search in a searchbar for whatever movie, show, actor, etc... that they are searching for. I'm pulling the user's search query and inserting it into an api request like this:
export const getDetails = (id) => {
return new Promise(function(resolve, reject) {
axios.get(`https://api.themoviedb.org/3/movie/` + id +`?api_key=&language=en-US`)
.then(function(response) {
resolve(response)
})
.catch(function(error) {
reject(error)
})
})
}
I'm able to get the data like this and console.log it:
import React, { Component } from 'react';
import Header from '../header';
import {Link} from 'react-router-dom';
import axios from 'axios';
import Footer from '../Footer.js';
import Searchbar from '../header/searchbar.js';
import List from '../results/list';
import {getDetails} from '../api/getDetails';
class Detail extends Component {
constructor(props) {
super(props);
this.state = {
id: this.props.match.params.id,
result: null,
error: false,
}
}
componentWillMount() {
getDetails(this.state.id).then(function(response){
this.setState({result: response});
console.log(response.data.original_title);
console.log(response.data.homepage);
console.log(response.data.popularity);
console.log(response.data.release_data);
console.log(response.data.overview);
}.bind(this)).catch(function(err) {
this.setState({
result:"There was a problem loading the results. Please try again.",
error: true
})
}.bind(this))
}
render() {
return(
<div>
<Header/>
<div className="details-container">
<h2>Details: </h2>
</div>
</div>
)
}
}
export default Detail
Console.logging it in the componentWillMount function successfully logs the data but I am not able to access the data in the render function via something like {response.data.orginal_title). How would I render the data being logged in componentWillMount?
TLDR; You can access your state variables from within your render function via this.state. Something like: console.log(this.state.result.data.origin_title) outside of the jsx and {this.state.response.data.orginal_title} inside the jsx.
P.S. You are using the correct this.
The following are picky recommendations and explanations, feel free to disregard.
It's recommended to make requests for data in componentDidMount. That can be read here in the docs for componentDidMount.
You're using arrow functions already in your get details function, if you convert the rest of your functions to arrow functions you no longer have to explicitly bind this to each one; it's automatically set be the this of it's parent. See the "No Separate This" section in the MDN docs
If you don't need any of the header information I would save response.data into your state so you don't have to type as much when you want to access the data. this.state.result.original_title vs this.state.result.data.original_title. That's just me and I'm lazy.
axios does return a promise like Eric said so you don't actually need to wrap it in the extra promise. You can just straight up return it and since arrow functions automatically return one line expressions you can spiff that up into a one liner:
export const getDetails = id => axios.get(`https://api.themoviedb.org/3/movie/${id}?api_key=&language=en-US`)
Finally you should be able to access the data you've stored in your state from your render function as mentioned in #3 above. Outside of the JSX you can console.log it like normal console.log(this.state.result), inside your JSX, however, you will need to make sure you escape with {} like: <div>{this.result.original_title}</div>
Small working example here: https://codesandbox.io/s/zqz6vpmrw3
You can simply use
{this.state.result}
inside the render.

Converting JSON response from oracle to angular 2 variable

I am trying to get the get the data from oracle db and displaying it. I have created a service using express api and node and able to run it successfully.
I have created angular service to fetch the data, and assign it in angular component, but i am not able to map the JSON response to the angular variable. Please check the code below and help me what i need to change in angular component.ts and how can i use that variable in html.
JSON Data from oracle DB:
[{"COUNT":27}]
angular service:
getCount(): Promise<String[]> {
return this.http.get(this.heroesUrl)
.toPromise()
.then(response => response.json().data)
.catch(this.handleError);
}
angular component.ts
dataGS : String[];
getData(): void {
this.dataService
.getCount()
.then(dataGS => this.dataGS = dataGS);
Your response does not have a property data, it's just an array. So instead of:
.then(response => response.json().data)
do:
.then(response => response.json())
Now you will get your array. Then as proposed by jitender you can iterate your response:
<div><p *ngFor="let d of dataGS ">{{d}}</p></div>
You can achieve this with the help of template bindings in angular.
For Example -
In your component you receive this.dataGS = [{"COUNT":27}] after getting the data from the db. Then on your html template you can display this with the help of Interpolation like
<div>{{dataGS[0].count}}</div>
What about
getCount(): Promise<String[]> {
return this.http.get(this.heroesUrl)
.toPromise()
.then(response => {
response.json().map(function(item) {
return item['COUNT'];
})
})
.catch(this.handleError);
}
in your html
<div><p *ngFor="let d of dataGS ">{{d}}</p></div>