Hi guys,
My goal is to send API response using remote method as:
Whenever I using 'string' as returns type, it always wrap my response with double quotes (")
...
returns: {
root: true,
type: 'string'
}
Result:
"this_is_a_response"
Also I have tried to set returns type as 'text/plain' and result still the same. Any workaround for this?
hey @tianp if I understand correctly, you are working with a remote method defined like this:
myModel.myResponse = function(callback) {
callback(null, "This is my response message.");
};
myModel.remoteMethod(
'myResponse', {
returns: [
{
arg: "message",
type: "string",
root: true
}
],
http: {
path: '/myResponse',
verb: 'get'
}
}
);
Well in Explorer(http://localhost:3000/explorer/), yes you always get the Response Body with double quotes ("). But that should be some format defined in Explorer instead of the message itself.
The message itself is not wrapped, suppose you display the message in front-end, you will get:
This is my response message.
instead of
"This is my response message"
Does this answer your question? Thanks!
Hi @jannyHou thank you for your response.
Yes, correct. Also I have tried using a simple curl in terminal and the response still wrapped in double quotes.
However, I found and applied a remote hook below:
myModel.afterRemote('myResponse', function(context, remoteMethodOutput, next) {
context.res.setHeader('Content-Type', 'text/plain');
context.res.end(context.result);
});
And does exactly what I need.
hey @tianp thank you for the perfect solution, there is a fault in my last comment, explorer doesn't wrap anything.
The "variable type" and "header content type" are different concepts. When you display a string in front-end or console.log it in back-end the double quotes are removed, but the header content is not in plain text.
Besides the applying of remote hook, this seems more like a node concept instead of a specific loopback concept :), but your solution is really helpful and welcomed here!
A few useful references:
The api doc of setHeader
and a useful link regarding "Content-type"
Since the question is solved I am closing issue here, feel free to reopen it if you have other thoughts :) Thank you!
@jannyHou understand. Thank you.
@tianp its should be added in documentation.I am trying to send html its always appending "".
Hi @jannyHou thank you for your response.
Yes, correct. Also I have tried using a simple curl in terminal and the response still wrapped in double quotes.
However, I found and applied a remote hook below:
myModel.afterRemote('myResponse', function(context, remoteMethodOutput, next) { context.res.setHeader('Content-Type', 'text/plain'); context.res.end(context.result); });And does exactly what I need.
I tried to do the same but calling context.res.end in afterRemote hook causes following warning:
UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:470:11)
Any clue to avoid it ?
For anyone who want to get a plain text response, the solution is to set the return type to "file" with "root" true, like below:
"returns": {
"arg": "data",
"type": "file",
"root": true
}
The reason is because the result is always get stringify by "res.json":
if (dataExists) {
if (this.resultType !== 'file') {
operationResults.sendBody(res, data, method);
res.end();
} else if (Buffer.isBuffer(data) || typeof(data) === 'string') {
res.end(data);
} else if (data.pipe) {
...
}
operationResults.sendBody is a method set from resolveReponseOperation, which can only be one of sendBodyJson, sendBodyJsonp, sendBodyJsonp and sendBodyJsonp, and non of them will be able to send a plain text response.
According the code, setting return type to "file" will skip operationResults.sendBody and send back a plain text response with res.end(data) if the result is string type.
Hope it help
Most helpful comment
Hi @jannyHou thank you for your response.
Yes, correct. Also I have tried using a simple curl in terminal and the response still wrapped in double quotes.
However, I found and applied a remote hook below:
And does exactly what I need.