Sailsjs socketio http status - express

I know I can call REST API of sails using socket.io. And return me the response. Following is a simple way to do that
socket.get("/", function (response) { console.log(response); })
But I also want the http status code along with response how I can get that?

If you're using the API blueprints, then the response will return the status code in the event of an error. For example, if there was a general server error, you'll get back:
{status: 500}
Otherwise, you'll get data in the response and you can assume the status was 200.
If you're using a custom controller action, then you can use any of the default responses (like res.serverError(), res.forbidden(), etc) to send back a status code, or you can set one yourself:
myAction: function (req, res) {
return res.forbidden(); // Will send {status: 403}
// OR
return res.json({status:400, error: 'Bad request!'})
}
But if you just send the status using res.json(500, {error: 'someError'}), you won't be able to retrieve it on the client.
Update
On Sails v0.10.x, using the new Sails socket client library, the request methods (io.socket.get, io.socket.post, etc) have callbacks that accept two arguments: the first being the response body (equivalent to the response in the previous client library version), and the second being an expanded response object which includes the status code, headers and more.

Related

Express res.send or res.json doesn't contain a body

I'm calling an API to fetch orders for a given user based on ID which are fetched from a third-party site. These are fetched correctly as a console.log them in the node server. But when I try to send the results back to the client neither res.send nor res.json results sending the data back to the client. Here is an example of an order from console.log:
{"customer":{"orders":{"edges":[{"node":{"id":"gid://shopify/Order/1234564564","lineItems":{"edges":[{"node":{"title":"Some title here"}}]}}}]}}}
Then on the client in the devtools when I console.log the response I get:
body:ReadableStream
locked:false
[[Prototype]]:ReadableStream
bodyUsed:false
headers:
Headers {}
ok:true
redirected:false
status:200
statusText:"OK"
type:"basic"
url:"http://localhost:9000/api/getOrders?cid=gid://shopify/Customer/1234564564"
[[Prototype]]:Response
Any help is appreciated.
=== UPDATE ===
I've now even tried the most basic of examples and am getting the same response on the client:
app.get('/testExpress', (req, res) => {
res.send("Hello")
});
Thanks to #laurent here is how I was able to receive that response on the client:
fetch('/testExpress')
.then(async (r) => {
const resp = await r.text();
console.log(resp);
})
You should try to get the json out of the response by const json = await response.json().
These are the available methods to parse the response body depending on what you want:
Response.arrayBuffer()
Returns a promise that resolves with an ArrayBuffer representation of the response body.
Response.blob()
Returns a promise that resolves with a Blob representation of the response body.
Response.clone()
Creates a clone of a Response object.
Response.formData()
Returns a promise that resolves with a FormData representation of the response body.
Response.json()
Returns a promise that resolves with the result of parsing the response body text as JSON.
Response.text()
Returns a promise that resolves with a text representation of the response body.
https://developer.mozilla.org/en-US/docs/Web/API/Response
The Response object is a representation of the http response. You should try to receive the body of the response by using one of these methods or parsing the body from the readable stream response.body.

How to get the data associated with the error response back?

I am making a request from the front-end to a route in my backend that is validating the token associated with a user, which would send an error response back to the front-end if the token has expired. I am sending some json with it but upon doing console.log of the error message in the catch block, the json sent along the error response is not shown.
Sending the error response like this
res.status(401).json({
message: 'User session has expired'
})
But the response that I am getting in the catch block in the front-end has no sign of the json sent with the error.
POST http://localhost:3001/check-validation 401 (Unauthorized)
Error: Request failed with status code 401
at createError (createError.js:17)
at settle (settle.js:19)
at XMLHttpRequest.handleLoad (xhr.js:78)
I don't understand why the json sent along the error response is not shown and how to get it?
Upon doing console.log of the error only the stacktrace of the error is shown and not the data associated with it. The data sent with it can be procured and depends on how the request has been made or by what library it has been made. If the request is made by axios then the following can be done:
axios.post('/formulas/create', {
name: "",
parts: ""
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error.response.data.message)
});
Here, in axios the details of the error would be wrapped up in error.response. Whereas, if the request was made by the fetch API then something following can resolve the problem:
fetch('/401').then(function(response) {
if (response.status === 401) {
return response.json()
}
}).then(function(object) {
console.log(object.message)
})
P.S I was searching a lot regarding this problem but didn't get an answer on SO, neither got any article or docs regarding it, even the official Express docs on error handling were not helpful. At last, I understood that the problem lies with the library that is being used to make the request. That's why answering my own question to mark the presence of this question on SO. A detailed discussion can be found here related to axios and here related to fetch api

Service Workers: Retrieve xhr body when fetching the request

How can I retrieve the body I sent from a xhr (XMLHttpRequest) send(body) call?.
My xhr variable is an XMLHttpRequest ready to call an internal url using the POST method (Ex: /path/api )
xhr.send("a=1");
On the other side, I have implemented a Service Worker and created the handler to catch all fetch requests
self.addEventListener('fetch', function(event, body)
{
event.respondWith( //Check content of event.request.body to run the right action );
}
I can retrieve some properties of the event.request as event.request.url, but I am unable to find the way to retrieve my original xhr body (i.e. "a=1").
Interestingly, when the Service Worker handles this request, and calls the network to get the result,
return fetch(event.request);
the server get access to the body data.
Below an extract of the Request object I receive within the SW fetch method
Request {method: "POST", url: "http://localhost/services", headers: Headers
, referrer: "http://localhost/m1/", referrerPolicy: "no-referrer-when-downgrade"…}
bodyUsed:false
credentials:"include"
headers:Headers
__proto__:Headers
integrity:""
method:"POST"
mode:"cors"
redirect:"follow"
referrer:"http://localhost/path/"
referrerPolicy:"no-referrer-when-downgrade"
url:"http://localhost/path/api"
Any suggestion on how to retrieve the content/body of the send request within the Service Worker fetch() capture?
Thanks!
This is maybe obvious for most people, but I wanted to add some notes with the response, in case someone is in my same situation in the future.
There are several methods to retrieve the body from the request, depending on how the body has been sent
event.request.arrayBuffer()
event.request.blob()
event.request.json()
event.request.text()
event.request.formData()
Any of those methods will return a Promise, which will include the body content. Voila!
I need to thank also Nikhil Marathe (https://hacks.mozilla.org/2015/03/this-api-is-so-fetching/) for helping me understand how all this works.

StrongLoop Loopback : How to customize HTTP response code and header

I'm looking for a way to customize StrongLoop LoopBack HTTP response code and headers.
I would like to conform to some company business rules regarding REST API.
Typical case is, for a model described in JSON, to have HTTP to respond to POST request with a code 201 + header Content-Location (instead of loopback's default response code 200 without Content-Location header).
Is it possible to do that using LoopBack ?
Unfortunately the way to do this is a little difficult because LoopBack does not easily have hooks to modify all responses coming out of the API. Instead, you will need to add some code to each model in a boot script which hooks in using the afterRemote method:
Inside /server/boot/ add a file (the name is not important):
module.exports = function(app) {
function modifyResponse(ctx, model, next) {
var status = ctx.res.statusCode;
if (status && status === 200) {
status = 201;
}
ctx.res.set('Content-Location', 'the internet');
ctx.res.status(status).end();
}
app.models.ModelOne.afterRemote('**', modifyResponse);
app.models.ModelTwo.afterRemote('**', modifyResponse);
};

Dojo JsonRestStore, fetch, onError callback and HTTP status code?

I would like to know how to obtain the HTTP status code returned after a fetch() operation is performed. I have specified the onComplete and onError callbacks to the fetch() call.
The onError is called in case of an error, but I am unable to obtain the HTTP status code from the parameter passed to onError (it's just the request, not the response).
With XhrGet I was able to get the status code from the ioArgs, and it seems that the JsonRestStore does not handle it that way.
I'm using Dojo 1.5.1 (and I really cannot upgrade yet to 1.6)
The error handler is given two arguments. The second argument (which I called config) has a property called xhr which contains... status and status text.
dojo.xhrGet({
url:'/bogusPath/',
error:function(error, config){
console.log('XHR-ErrorHandle',arguments);
console.log('XHR-ErrorHandle-status:',config.xhr.status);
console.log('XHR-ErrorHandle-statusText:',config.xhr.statusText);
}
})
Returns:
XHR-ErrorHandle [Error, Object]
XHR-ErrorHandle-status: 404
XHR-ErrorHandle-statusText: Not Found