I have a JSON read to UI and modifiled as part of review process. Finally I want to save New data to a New folder/File.
Code Sample below - Always ends with POST call in error :
SaveFinalData(){
this.postJson<Reaction>
('./assets/ICP/Reviewed/Json/out.json',
this.reactionDatabase.reactiondataChange.value);
}
postJson<Reaction>(url: string, Reaction: any){
//let body = JSON.stringify({ Reaction });
this.http.post(url, body)
.subscribe(
(val) => {
console.log("POST call successful value returned in body", val);
},
response => {
console.log("POST call in error", response);
},
() => {
console.log("The POST observable is now completed.");
});
}
Have tried below 2 alternatives:
(1)
var theJSONdata = JSON.stringify({ Reaction });
window.localStorage.setItem('./assets/ICP/Reviewed/Json/out.json', theJSONdata)
Result -- NO LUCK!
(2)
var jsonfile = require('jsonfile')
var file = './assets/ICP/Reviewed/Json/out.json'
var obj = {name: 'JP'} //SAMPLE DATA
jsonfile.writeFile(file, obj, function (err) {
console.error(err)
})
Result -- NO LUCK! --> GIVES ERROR fs.writeFile is not a function
Pls kindly help/guide me to reach the final result....Thanks
Related
This question already has answers here:
How can I get the status code from an HTTP error in Axios?
(15 answers)
Closed 7 days ago.
I'm using blob responseType with Axios in my VueJS app for downloading a document from the server. When the response code is 200 it works fine and download the file but when there is any http error, I'm not able to read the status code when I catch the error because the error is a JSON response.
Has anyone had a similar issue and worked out a way to convert the blob response type to json and thrown an error based on the status code?
I have tried sending the response as a plain text from Laravel backend and tried converting the response to JSON or text in the front-end but no luck.
I have tried reading error response headers but no luck.
Axios({
url: 'xxxx',
method: 'GET',
responseType: 'blob',
})
.then((response) => {
//code to read the response and create object url with the blob and download the document
})
.catch((error) => {
console.log('Error', error.message); //nothing
console.log('Error', error.error); //undefined
console.log('Error', error.data); //undefined
const blb = new Blob([error], {type: "text/plain"});
const reader = new FileReader();
// This fires after the blob has been read/loaded.
reader.addEventListener('loadend', (e) => {
const text = e.srcElement.result;
console.log(text);
});
// Start reading the blob as text.
reader.readAsText(blb);
});
I just want to throw the error message based on the status code. If it's 401 just want it to be unauthorized and anything else throw it on to the component.
The reason is that the response type is blob.
In case of error, the status code is available directly in your exception object. However, the response is a promise.
What you need to do is:
.catch((error) => {
let statusCode = error.response.status
let responseObj = await error.response.data.text();
:
:
For more details you can read documentation.
You can do this, it cast the error in JSON if it's a blob or let the response data as it received and you can do work with it.
let errorString = error.response.data;
if (
error.request.responseType === 'blob' &&
error.response.data instanceof Blob &&
error.response.data.type &&
error.response.data.type.toLowerCase().indexOf('json') != -1
) {
errorString = JSON.parse(await error.response.data.text());
}
alert(errorString);
You need to convert the response blob to json:
Axios({
url: 'xxxx',
method: 'GET',
responseType: 'blob',
})
.then((response) => {
//code to read the response and create object url with the blob and download the document
})
.catch((error) => {
if (
error.request.responseType === 'blob' &&
error.response.data instanceof Blob &&
error.response.data.type &&
error.response.data.type.toLowerCase().indexOf('json') != -1
) {
new Promise((resolve, reject) => {
let reader = new FileReader();
reader.onload = () => {
error.response.data = JSON.parse(reader.result);
resolve(Promise.reject(error));
};
reader.onerror = () => {
reject(error);
};
reader.readAsText(error.response.data);
})
.then(err => {
// here your response comes
console.log(err.response.data)
})
};
});
You can use this inside interceptor.
For more info
I believe you might be using the error variable in your catch() incorrectly.
Axios passes an error object that has a response property that is where you will want to look for your error or message.
https://github.com/axios/axios#handling-errors
On a side note if you can catch the error server side you could try setting the Content-type header to text/plain. Using either header('Content-Type: plain/text') or Laravel's Response Methods
you can do the following way
axios.post("URL", data, {
validateStatus: (s) => s <= 500,
responseType: 'blob',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/pdf'
}
})
.then(async (response) => {
if (response.status !== 200) {
// error handling
const error = JSON.parse(await response.data.text());
console.log('error: ', error);
alert(error.message);
} else {
console.log('res', response)
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.pdf'); //or any other extension
document.body.appendChild(link);
link.click();
}
})
You can convert blob response globaly:
$axios.onError(async ({request, response}) => {
const status = response.status
let data = response.data
if (request.responseType === 'blob' && data instanceof Blob && data.type) {
const text = await data.text()
data = data.type.toLowerCase().includes('json') ? JSON.parse(text) : text
}
throw {status, data} // error model
})
catch(async(error) => {
const errorJson = JSON.parse(await error.response.data.text());
console.log('error: ', errorJson.error_message);
})
After reading up on this topic for the last 2.5 hours I cant determine how to fix my: Cannot set headers after they are sent to the client issue, but I think it has to do with the below code at the bottom especially the code is in bold.
Any help or assistance will be greatly appreciated.
app.post("/api/tracking/retrieve", (req, res) => {
res.setHeader('Content-Type', 'application/json');
// before all the iterations
const trackingCodes = ['EZ6000000006', 'EZ4000000004'];
const carrierCodes = ['UPS', 'UPS'];
trackingCodes.forEach((trackingCode) => {
carrierCodes.forEach((carrierCode) => {
const tracker = new api.Tracker({
tracking_code: trackingCode,
carrier: carrierCode
})
tracker.save().then(function (data) {
table = 'tracking_table';
col = ['user_id', 'tracking_number'];
val = [user_id, tracker.tracking_code];
**// !ISSUE: :: ::: :::: ::::: :::::: ::::::: //**
main.create(table, col, val, function (data) {
res.send(JSON.stringify({
id: "",
user_id: user_id,
tracking_number: data.tracking_code
})); // replace this for your res.json()
});
}
)
.catch(error => {
// handle errors
console.log('There has been an error with your submission.')
});
})
})
res.end()
});
As #kiran Mathew has answered, the res.json() are called again and again inside for loop which is why 'cannot set headers after response sent' occurs.
You could have a result array 'trackingNumbers' to store all tracking_number and later exiting from the loop, sent a single response.
app.post("/api/tracking/retrieve", (req, res) => {
const trackingCodes = ["EZ6000000006", "EZ4000000004"];
const carrierCodes = ["UPS", "UPS"];
const trackingNumbers = [];
trackingCodes.forEach(trackingCode => {
carrierCodes.forEach(carrierCode => {
const tracker = new api.Tracker({
tracking_code: trackingCode,
carrier: carrierCode
});
tracker
.save()
.then(function(data) {
table = "tracking_table";
col = ["user_id", "tracking_number"];
val = [user_id, tracker.tracking_code];
// !ISSUE: :: ::: :::: ::::: :::::: ::::::: //**
main.create(table, col, val, function(data) {
// res.json({
// id: "",
// user_id: user_id,
// tracking_number: data.tracking_code
// });
trackingNumbers.push(data.tracking_code);
});
})
.catch(error => {
// handle errors
console.log("There has been an error with your submission.");
});
res.json({
id: "",
user_id: user_id,
tracking_number: trackingNumbers
});
});
});
});
The issue with your code is you are calling res.json() in an iterative loop.
You should call that only once since
res.json() implements res.write(),res.setHeaders() and res.end() under the hood,
which means once res.end() is called it ends the request and cannot send anymore.
You are better off writing the responses using
res.setHeader('Content-Type', 'application/json'); // before all the iterations
res.send(JSON.stringify({key:"value"})); // replace this for your res.json()
res.end() // after iterations
I would like to scrape this page: calendar events
for specific data, like formattedDate and description. How do I go about that in a module in Node.JS. I am having a hard time understanding the process in Node.JS.
Any help would go a long way, thanks in advance.
it's pretty simple, you can import the request module and use it. For example, see code below.
const request = require("request");
request("MY_URL", (error, response, body) => {
console.log('body:', body);
});
Also, you can try this here, on Repl.it
First of all, you need to parse your JSON, this allows you to access fields from received json.
const data = JSON.parse(body);
Now, if you want to access some information about an event you need to loop events and access what you need, something like:
const events = data.bwEventList.events;
events.map((data, index) => console.log(data.calendar))
Final code also on Repl.it
from nodeJS docs here
const http = require('http');
http.get('http://umd.bwcs-hosting.com/feeder/main/eventsFeed.do?f=y&sort=dtstart.utc:asc&fexpr=(categories.href!=%22/public/.bedework/categories/sys/Ongoing%22%20and%20categories.href!=%22/public/.bedework/categories/Campus%20Bulletin%20Board%22)%20and%20(entity_type=%22event%22%7Centity_type=%22todo%22)&skinName=list-json&count=30', (res) => {
const { statusCode } = res;
const contentType = res.headers['content-type'];
let error;
if (statusCode !== 200) {
error = new Error('Request Failed.\n' +
`Status Code: ${statusCode}`);
}
if (error) {
console.error(error.message);
// consume response data to free up memory
res.resume();
return;
}
res.setEncoding('utf8');
let rawData = '';
res.on('data', (chunk) => { rawData += chunk; });
res.on('end', () => {
try {
const parsedData = JSON.parse(rawData);
console.log(parsedData["bwEventList"]["resultSize"]);
} catch (e) {
console.error(e.message);
}
});
}).on('error', (e) => {
console.error(`Got error: ${e.message}`);
});
see console.log(parsedData["bwEventList"]["resultSize"]);
slice parsedData as an array until you get what you want
everybody! I'm trying to build a Google Pagespeed client in nodejs.
I get a json file with syntax errors for any url. For example: url: http://www.bbc.com/ , error: enter image description here
json file:enter image description here
I need only the property "ruleGroups". I tried to extract it so jsonpath.query(d, '$.ruleGroups') -
did not work out.
Help please understand, sorry if the issue is dilettian.
let key = 'key';
let url = 'http://www.bbc.com/';
let strategy = 'desktop';
https.get({
host: 'www.googleapis.com',
path: '/pagespeedonline/v4/runPagespeed?url=' + encodeURIComponent(url) +
'&key='+key+'&strategy='+strategy
}, function (res) {
console.log ("statusCode:", res.statusCode);
console.log ("headers: ", res.headers);
res.on ('data', function (d) {
let json = JSON.parse(d);
fs.appendFile('log.txt', json);
});
}). on ('error', function (e) {
console.error (e);
});
You may need to accumulate all the data, then parse in the “end” event:
let rawData = '';
res.on('data', (chunk) => { rawData += chunk; });
res.on('end', () => {
try {
const parsedData = JSON.parse(rawData);
console.log(parsedData);
} catch (e) {
console.error(e.message);
}
});
More information: https://nodejs.org/api/http.html#http_http_get_options_callback
Wanted to see if I could make a bot (just for myself, not to spam. Obviously!) and took the following steps:
Download Node.js from the main site.
Created an app on Twitter and all that stuff.
Tried it a ton of ways and then read this blog: http://www.apcoder.com/2013/10/03/twitter-bot-20-minutes-node-js/
Now, I am here: https://github.com/ttezel/twit I installed it from the terminal and got back:
node_modules/twit
└── oauth#0.9.9
Then I went to include the following (with my Twitter app details included) and got pages and pages of errors. I checked on ShellCheck and it's mostly parsing errors. But as it was just copy and paste, I think I must be doing something else wrong.
Any ideas?
var Twit = require('twit')
var T = new Twit({
consumer_key: '...'
, consumer_secret: '...'
, access_token: '...'
, access_token_secret: '...'
})
//
// tweet 'hello world!'
//
T.post('statuses/update', { status: 'hello world!' }, function(err, data, response) {
console.log(data)
})
//
// search twitter for all tweets containing the word 'banana' since Nov. 11, 2011
//
T.get('search/tweets', { q: 'banana since:2011-11-11', count: 100 }, function(err, data, response) {
console.log(data)
})
//
// get the list of user id's that follow #tolga_tezel
//
T.get('followers/ids', { screen_name: 'tolga_tezel' }, function (err, data, response) {
console.log(data)
})
//
// retweet a tweet with id '343360866131001345'
//
T.post('statuses/retweet/:id', { id: '343360866131001345' }, function (err, data, response) {
console.log(data)
})
//
// destroy a tweet with id '343360866131001345'
//
T.post('statuses/destroy/:id', { id: '343360866131001345' }, function (err, data, response) {
console.log(data)
})
//
// get `funny` twitter users
//
T.get('users/suggestions/:slug', { slug: 'funny' }, function (err, data, response) {
console.log(data)
})
//
// post a tweet with media
//
var b64content = fs.readFileSync('/path/to/img', { encoding: 'base64' })
// first we must post the media to Twitter
T.post('media/upload', { media: b64content }, function (err, data, response) {
// now we can reference the media and post a tweet (media will attach to the tweet)
var mediaIdStr = data.media_id_string
var params = { status: 'loving life #nofilter', media_ids: [mediaIdStr] }
T.post('statuses/update', params, function (err, data, response) {
console.log(data)
})
})
//
// stream a sample of public statuses
//
var stream = T.stream('statuses/sample')
stream.on('tweet', function (tweet) {
console.log(tweet)
})
//
// filter the twitter public stream by the word 'mango'.
//
var stream = T.stream('statuses/filter', { track: 'mango' })
stream.on('tweet', function (tweet) {
console.log(tweet)
})
//
// filter the public stream by the latitude/longitude bounded box of San Francisco
//
var sanFrancisco = [ '-122.75', '36.8', '-121.75', '37.8' ]
var stream = T.stream('statuses/filter', { locations: sanFrancisco })
stream.on('tweet', function (tweet) {
console.log(tweet)
})
//
// filter the public stream by english tweets containing `#apple`
//
var stream = T.stream('statuses/filter', { track: '#apple', language: 'en' })
stream.on('tweet', function (tweet) {
console.log(tweet)
})