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

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

Related

Read JSON file from file in Angular

I have a JSON file config.json saved in the src/app/config directory.
[
"caseSensitive",
"matchKeywords",
"items"
]
I have to read the file and get the content of the JSON file without parsing it.
After searching for it, I got two ways
Add "resolveJsonModule": true to the tsconfig.json file
Declara a typing module declare module "*.json" {}
and importing JSON as
import * as data from './app/config/config.json';
export class SchemaService {
constructor() { }
getConfig() {
console.log('bool: ', data); // Output in screenshot
console.log('type: ', typeof BooleanData); // object
console.log('parsed: ', JSON.stringify(BooleanData));
}
}
But both the ways are giving the parsed output as
The JSON.stringify(BooleanData) statement is not giving the actual JSON file, instead, the array items are changed to key-value where the index is represented as key
{
"0":"caseSensitive",
"1":"matchKeywords",
"2":"items"
}
How can I read the raw JSON (without parsing) in Angular, or at least convert an object into JSON?
You can use a quickfix provide by #amer-yousuf But it will also let you import any .js file into your codebase as well. I wont prefer that. Here is an alternative approach
Define your config.json.ts (notice it ends with .ts and not .json) something like below
export const CONFIG = { // your JSON is assigned to CONFIG variable
"say": "hello world"
}
In your other .ts file where you want to use, use something like following code
import { CONFIG } from './config.json';
// ...
console.log(CONFIG.say);
// ...
Benefit of this method:
You can still use tslint/eslint on config.json.ts
Most editors will auto-complete for you
In Angular, to access the JSON as an object, you need to add the following two options to the tsconfig.json file:
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
Then you can import it within your service like the following:
import data from './app/config/config.json';
To access JSON as Module in Angular you should add these two lines into tsconfig.json file
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true
Then you can import it anywhere you want within the app
import * as Characters from './configs/characters.json';
Finaly access the object from module
export class CharactersComponent {
public characters: CharacterModel[] = (Characters as any).default;
}

Import csv into Nextjs and read with d3

I'm having trouble importing csv data into my nextjs app to read with d3.
I understand that static files must be in the public directory and only absolute paths will work, but although I get the absolute path with process.cwd(), it doesn't seem to find the file. I can't import the csv at the top of the js file either?
My index.js is
import { useState, useEffect } from 'react'
import path from 'path'
import Head from 'next/head'
import { csv } from "d3"
export async function getStaticProps(context) {
const dataPath = path.join(process.cwd(), 'public/data/harry_potter.csv')
console.log("DATA PATH: ", typeof dataPath)
const data = await csv(dataPath)
console.log("DATA", data)
if (!data) {
return {
notFound: true,
}
}
return {
props: {}, // will be passed to the page component as props
}
}
export default function Home(props) {
useEffect(() => {
console.log("DATA", props)
}, [])
return (
<div className="container">
<Head>
<title>d3 exercise</title>
</Head>
<main>
</main>
</div>
)
}
My path is:
C:\Users\david\Documents\d3-pluralsight\ex1\public\data\harry_potter.csv
And the nextjs app directory is
C:\Users\david\Documents\d3-pluralsight\ex1
But I still get:
TypeError: Only absolute URLs are supported
I can't import like this either
import harry from '../public/data/harry_potter.csv'
Am I missing something? Does Next not recognise csv files without extra config?
EDIT: using csv-loader loads the csv, but doesn't give access to d3's powerful type conversion functions. If I just write my own function js runs out of memory with csvs with 20000 rows
d3.csv is expecting a URL, not a file path (older versions of d3.csv would start a XHR request; newer versions retrieve via fetch). If you want to read the file off the filesystem (as opposed to serving it via HTTP), just read it into a string with something like fs and then pass the string to d3.csvParse.

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.

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

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

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);
});