I try to update JSON file in backend with express and display new datas on frontend. But currently when I do request I get good response but data don't change.
Server Express (route) Script to edit JSON:
function editJSON(fr,en,es){
var obj = {
list_words: []
}
fs.readFile('./assets/words.json', 'utf-8', (err, jsonString) =>{
if(err){
console.log(err)
}else {
try{
obj = JSON.parse(jsonString)
obj.list_words.push({fr: fr, en: en, es: es})
json = JSON.stringify(obj)
fs.writeFileSync('./assets/words.json',json,'utf-8',function (err){
if (err) throw err;
console.log('complete');
})
} catch (err){
console.log(" Error parsing JSON", err)
}
}
})
}
And below script to send data and other to display.
methods: {
async addWord () {
var obj = {
fr: this.words_input.fr,
en: this.words_input.en,
es: this.words_input.es
}
const res = await axios.post('http://localhost:3000/addwords', obj)
const data = res.data
console.log(data)
}
},
mounted: async function () {
await axios.get('http://localhost:3000/words.json')
.then(response => {
this.words_init = response.data
})
.catch(error => {
console.log('There was an error: ' + error.response)
})
}
If I restart server after request table with new data is displayed. If you know how I can display informations without restart server this can help me so much.
I tried this
const res = await axios.post('http://localhost:3000/addwords', obj)
const data = res.data.list_words
this.words_init = data
With this route
app.post('/addwords',(req,res)=>{
console.log(req.body.fr)
const fr = req.body.fr
const en = req.body.en
const es = req.body.es
editJSON(fr,en,es)
console.log(fr)
res.send(words)
res.status(201).send('created User')
res.end()
})
But I got error
"Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client"
From back
and
"[Vue warn]: Error in v-on handler (Promise/async): "Error: Request aborted"
From frontend
const res = await axios.post('http://localhost:3000/addwords', obj)
this.words_init = res.data.list_words
```
with this route everything work But mu new list don't display
You need to return latest JSON on post response and then assign it to this.words_init variable.
Related
I have this request in server.js file.
app.post("/insertRowtoMain", (req, res) => {
const {nodeid, maintenancetype, personnel, process, date} = req.body;
//console.log("description",description)
let insertQuery = `insert into maintenance(nodeid,maintenancetype, personnel, process, date)
values(${nodeid},'${maintenancetype}',${personnel},'${process}', '${date}') returning id`
pool.query(insertQuery, (err, result) => {
if (!err) {
console.log("insertRowtoMain", result.rows);
res.status(200).send(result.rows);
} else {
res.status(404).json(err.message)
console.log("insertRowtoMain error", err.message)
}
})
})
And I am calling this request function in front-end with this code:
const addNewMainTypes = async () => {
try {
await axios.post(`${serverBaseUrl}/insertRowtoMain`, {
nodeid: newMaintenance.nodeid,
maintenancetype: newMaintenance.maintenancetype,
personnel: newMaintenance.personnel,
process: newMaintenance.process,
date: newMaintenance.date,
});
} catch (err) {
throw err;
}
const maintenance = await getMain();
// console.log("main list", maintenanceList);
setMaintenance(maintenance);
const maintenanceList = await getMainTypes();
// console.log("main list", maintenanceList);
setMaintenanceList(maintenanceList);
};
When I insert a new row to this function, I got the returning id in server.js terminal.
How can I use that Id in front-end?
Save the response of the POST request in a variable and access the data property
// Here, "data" will be a variable with the response data
const { data } = await axios.post(`${serverBaseUrl}/insertRowtoMain`, {
nodeid: newMaintenance.nodeid,
maintenancetype: newMaintenance.maintenancetype,
personnel: newMaintenance.personnel,
process: newMaintenance.process,
date: newMaintenance.date,
});
/* Seems like your API is returning an array of objects with "id" property, so, for example... */
// The following should console.log the first element's id of the array
console.log(data[0]?.id);
From the example code on the gtfs-realtime-bindings library's documentaion,
I tried to put similar logic inside my router but was not able to take the result out of request()
route.get('/', (req, res) => {
const data = [];
request(requestSettings, function (error, response, body) {
if (!error && response.statusCode == 200) {
const feed = GtfsRealtimeBindings.transit_realtime.FeedMessage.decode(body);
feed.entity.forEach(function(entity) {
if (entity.tripUpdate) {
data.push(entity.tripUpdate);
}
});
}
res.status(200).json( data );
}); // empty array returns
Then I tried to use axios, but decode() raise "Error: illegal buffer"
const realtimeRequest = () => {
axios.get('https://opendata.hamilton.ca/GTFS-RT/GTFS_TripUpdates.pb')
.then(function (body) {
const feed = GtfsRealtimeBindings.transit_realtime.FeedMessage.decode(body.data);
// body.data looks like this '\x03436\x12\x041219 ����\x06'
return feed;
}).catch(error => console.log(error));
}
route.get('/', (req, res) => {
realtimeRequest()
.then(() => {
res.status(200).json( data );
})
}
/**
Error: illegal buffer
at create_typed_array (/node_modules/protobufjs/src/reader.js:47:15)
at create_buffer (/node_modules/protobufjs/src/reader.js:69:19)
at Function.create_buffer_setup (/node_modules/protobufjs/src/reader.js:70:11)
at Function.decode (/node_modules/gtfs-realtime-bindings/gtfs-realtime.js:134:34) **/
For the axios request, try adding responseType: 'arraybuffer'.
This worked for me for the same issue stated for "axios, but decode() raise 'Error: illegal buffer'"
I am new to React and Node js. I have defined a function that run a Python script from my Node.js application using child process, and I have an router post that called pythonExecute and return that result back to
React. Router seemed to have trouble sending the data back to react using react.json(data),can someone please help and see what I did wrong and how to fix it?
Function
const pythonExecute = (data, input) => {
const res = {
err: false,
msg: ""
}
return new Promise((resolve, reject)=>{
const fileName = "test.py"
saveFile(fileName, data)
.then(()=>{
const filePath = path.join(__dirname,"../test.py")
const spawn = require("child_process").spawn;
const pythonProcess = spawn('python',[filePath]);
pythonProcess.stdout.on('data', (data) => {
console.log(data.toString());
resolve(data)
});
})
.catch(()=>{
console.log("ERROR SAVE FILE"+ saveFileRes)
const err = {
err: true,
output: "Internal Server Error!"
}
resolve(err)
})
})
Express Router
const execute = require('../../compile/compile')
router.post('/submit', (req,res)=>{
console.log(req.body)
const code = req.body.code
const input = req.body.input
const lang = req.body.lang
return execute.pythonExecute(code, input)
.then(data=>{
console.log("SUCCESSFULL PROMISE " + data)
console.log("SENDING " + data)
res.write(data)
deleteFile(path.join(__dirname, '../../test.py'))
})
.catch(err => {
console.log("ERROR PROMISE " + err)
deleteFile(path.join(__dirname, '../../test.py'))
})
}
)
React
export default class Ide extends Component {
state={
code: code.cpp,
result: 'Submit Code to See Result',
lang: 'cpp'
}
onSubmitHandler = (e) => {
e.preventDefault()
alert("submit code")
axios.post(`${secret.url}code/submit`,this.state)
.then(res=>{
console.log(res.data)
const data = res.data
if(data.err){
// Error in user code
this.setState({
result: data.error
})
}else{
this.setState({
result: data.output
})
}
})
.catch(err=>{
console.log(err)
})
}
Logs
Server started at port 8000
{
code: '# Your code will come here\nprint("b")',
result: 'Submit Code to See Result',
lang: 'python'
}
SAVING FILES
The file was saved!
FILE PATH >> \ide-server\test.py
[6 7 8]
SUCCESSFULL PROMISE [6 7 8]
SENDING [6 7 8]
File deleted!
SORRY NOT DELETED
File deleted!
File deleted!
if you want to send a JSON structure to react App try to do on server:
res.send(JSON.stringify(data))
data must be like {values: [6, 7, 8]} or smth else
on client:
axios.post(`${secret.url}code/submit`,this.state)
.then(res=> res.json())
.then(result => console.log(result))
...
if you want to send a plain text:
res.send(data)
on client:
axios.post(`${secret.url}code/submit`,this.state)
.then(res=> res.text())
.then(result => console.log(result))
...
And don't forget use res.end() after res.write();
I am working on a react app and am trying to find a way to pass a variable I define in my front-end (Question.js) to my back-end (server.js) so that I can issue different queries. I have the code
//Question.js
state = {
data: null
};
componentDidMount() {
this.callBackendAPI()
.then(res => this.setState({ data: res.express }))
.catch(err => console.log(err));
}
callBackendAPI = async () => {
const response = await fetch('/express_backend');
const body = await response.json();
if (response.status !== 200) {
throw Error(body.message)
}
return body;
};
//server.js
con.connect(function (err) {
if (err) throw err;
con.query("SELECT question FROM s1questions WHERE ID = 1", function (err, result, fields) {
if (err) throw err;
app.get('/express_backend', (req, res) => {
var x = JSON.stringify(result[0].question);
res.send({ express: `${x}` });
});
});
});
Your sever should probably split your database connection from your route handler definitions. Also, you could use query parameters to access questions based on their id in the database.
// question.js
callBackendAPI = async () => {
const response = await fetch(`/express_backend?questionId=1`);
const body = await response.json();
if (response.status !== 200) {
throw Error(body.message)
}
return body;
};
// server.js
app.get('/express_backend', (req, res) => {
const { questionId } = req.query;
// query database for question by id
});
Is it sensible to use Node.js to write a stand alone app that will connect two REST API's?
One end will be a POS - Point of sale - system
The other will be a hosted eCommerce platform
There will be a minimal interface for configuration of the service. nothing more.
Yes, Node.js is perfectly suited to making calls to external APIs. Just like everything in Node, however, the functions for making these calls are based around events, which means doing things like buffering response data as opposed to receiving a single completed response.
For example:
// get walking directions from central park to the empire state building
var http = require("http");
url = "http://maps.googleapis.com/maps/api/directions/json?origin=Central Park&destination=Empire State Building&sensor=false&mode=walking";
// get is a simple wrapper for request()
// which sets the http method to GET
var request = http.get(url, function (response) {
// data is streamed in chunks from the server
// so we have to handle the "data" event
var buffer = "",
data,
route;
response.on("data", function (chunk) {
buffer += chunk;
});
response.on("end", function (err) {
// finished transferring data
// dump the raw data
console.log(buffer);
console.log("\n");
data = JSON.parse(buffer);
route = data.routes[0];
// extract the distance and time
console.log("Walking Distance: " + route.legs[0].distance.text);
console.log("Time: " + route.legs[0].duration.text);
});
});
It may make sense to find a simple wrapper library (or write your own) if you are going to be making a lot of these calls.
Sure. The node.js API contains methods to make HTTP requests:
http.request
http.get
I assume the app you're writing is a web app. You might want to use a framework like Express to remove some of the grunt work (see also this question on node.js web frameworks).
/*Below logics covered in below sample GET API
-DB connection created in class
-common function to execute the query
-logging through bunyan library*/
const { APIResponse} = require('./../commonFun/utils');
const createlog = require('./../lib/createlog');
var obj = new DB();
//Test API
routes.get('/testapi', (req, res) => {
res.status(201).json({ message: 'API microservices test' });
});
dbObj = new DB();
routes.get('/getStore', (req, res) => {
try {
//create DB instance
const store_id = req.body.storeID;
const promiseReturnwithResult = selectQueryData('tablename', whereField, dbObj.conn);
(promiseReturnwithResult).then((result) => {
APIResponse(200, 'Data fetched successfully', result).then((result) => {
res.send(result);
});
}).catch((err) => { console.log(err); throw err; })
} catch (err) {
console.log('Exception caught in getuser API', err);
const e = new Error();
if (err.errors && err.errors.length > 0) {
e.Error = 'Exception caught in getuser API';
e.message = err.errors[0].message;
e.code = 500;
res.status(404).send(APIResponse(e.code, e.message, e.Error));
createlog.writeErrorInLog(err);
}
}
});
//create connection
"use strict"
const mysql = require("mysql");
class DB {
constructor() {
this.conn = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'pass',
database: 'db_name'
});
}
connect() {
this.conn.connect(function (err) {
if (err) {
console.error("error connecting: " + err.stack);
return;
}
console.log("connected to DBB");
});
}
//End class
}
module.exports = DB
//queryTransaction.js File
selectQueryData= (table,where,db_conn)=>{
return new Promise(function(resolve,reject){
try{
db_conn.query(`SELECT * FROM ${table} WHERE id = ${where}`,function(err,result){
if(err){
reject(err);
}else{
resolve(result);
}
});
}catch(err){
console.log(err);
}
});
}
module.exports= {selectQueryData};
//utils.js file
APIResponse = async (status, msg, data = '',error=null) => {
try {
if (status) {
return { statusCode: status, message: msg, PayLoad: data,error:error }
}
} catch (err) {
console.log('Exception caught in getuser API', err);
}
}
module.exports={
logsSetting: {
name: "USER-API",
streams: [
{
level: 'error',
path: '' // log ERROR and above to a file
}
],
},APIResponse
}
//createlogs.js File
var bunyan = require('bunyan');
const dateFormat = require('dateformat');
const {logsSetting} = require('./../commonFun/utils');
module.exports.writeErrorInLog = (customError) => {
let logConfig = {...logsSetting};
console.log('reached in writeErrorInLog',customError)
const currentDate = dateFormat(new Date(), 'yyyy-mm-dd');
const path = logConfig.streams[0].path = `${__dirname}/../log/${currentDate}error.log`;
const log = bunyan.createLogger(logConfig);
log.error(customError);
}
A more easy and useful tool is just using an API like Unirest; URest is a package in NPM that is just too easy to use jus like
app.get('/any-route', function(req, res){
unirest.get("https://rest.url.to.consume/param1/paramN")
.header("Any-Key", "XXXXXXXXXXXXXXXXXX")
.header("Accept", "text/plain")
.end(function (result) {
res.render('name-of-the-page-according-to-your-engine', {
layout: 'some-layout-if-you-want',
markup: result.body.any-property,
});
});