Can't return value when getting 400 response in Meteor HTTP.post() - meteor

I want to return a value from server side to client side, If I get error response from the API Call.
if Meteor.isClient
Meteor.call 'foo',data,(err,results)->
console.log(results)
if Meteor.isServer
Meteor.methods foo:(data)->
results = Meteor HTTP.post "example.com",{
data: data
},(err,results)
if err
console.log('abc')
return 0
If I get 400 error from example.com, then It is printing abc but it is not returning anything to the client.
Thanks in advance,

As #user3374348 stated, you should use HTTP.post synchronously if you want your method to return its results. Otherwise, HTTP.post's callback will return the result (to nowhere), not your foo method. Here's how you would do it, in regular JavaScript:
if (Meteor.isServer) {
Meteor.methods({
foo: function (data) {
try {
var result= HTTP.post("example.com", {
data: data
});
return result;
}
catch (error) {
// todo: check if the error is 400
console.log("abc");
return 0;
}
}
});
}

Related

Extracting data out of http call [duplicate]

I'm using Meteor for first time and i'm trying to have a simple http call within a method so i can call this method from the client.
The problem is that this async call it's keep running even if i put it within a wrapper.
Client side:
Meteor.call('getToken', function(error, results) {
console.log('entered');
if(error) {
console.log(error);
} else {
console.log(results);
}
});
Server Side
Meteor.methods({
getToken: function(){
// App url
var appUrl = 'myAppUrl';
// Key credentials
var apiKey = 'mykey';
var apiSecret = 'mySecret';
function asyncCall(){
Meteor.http.call(
'POST',
appUrl,
{
data: {
key: apiKey,
secret: apiSecret
}
}, function (err, res) {
if(err){
return err;
} else {
return res;
}
}
);
}
var syncCall = Meteor.wrapAsync(asyncCall);
// now you can return the result to client.
return syncCall;
}
});
I'm always getting an undefined return.
If i log the response within the http.post call i'm geting the correct response.
If i try to log the syncCall i get nothing.
I would very appreciate any help on this.
You should use the synchronous version of HTTP.post in this case. Give something like this a try:
Meteor.methods({
getToken: function() {
var appUrl = 'myAppUrl';
var data = {apiKey: 'mykey', apiSecret: 'mySecret'};
try {
var result = HTTP.post(appUrl, {data: data});
return result;
} catch (err) {
return err;
}
}
});
Instead of returning the err I'd recommend determining what kind of error was thrown and then just throw new Meteor.Error(...) so the client can see the error as its first callback argument.

meteorjs get data returned from server callback

In meteor im trying to insert a new document by making a Meteor.call from the client. Everything is working ok, except that I want to return the id of create document to the client, so that i can redirect to the proper url.
I have something similar to this (client):
Meteor.call('scenarioCreate', scenarioObj, function(err, response) {
if(err) {
console.warn(err);
return;
}
console.info(response);
});
On server:
Meteor.methods({
'scenarioCreate': function(scenarioObj) {
Scenarios.insert( scenarioObj, function(err, id) {
console.info("new id: "+id);
if (err) {
console.warn(err);
throw new Meteor.Error(404, 'Something went wrong');
}
return id;
});
}
});
From the server side i get the console log "new id: DDaq4aWsGf3fxG7RP", but I should get that same value on the client on the "response" value, but I always get undefined.
Can anybody explain to me why or what I am doing wrong.
Meteor.methods doesn't wait for your callback. Try this:
On server:
Meteor.methods({
'scenarioCreate': function(scenarioObj) {
var newId = Scenarios.insert(scenarioObj);
return newId;
}
});
To catch any error, use try/catch
Note: If you still want to use callback, checkout fibers/future.
Your first error is that you are returning id inside the callback for insert. That doesn't do anything. Then your second is not knowing that methods are synchronously executed. That would mean that you could only use the information available inside the callback using Meteor.wrapAsync. But that's besides the point. The insert function returns the new _id. Meaning you can do this:
Meteor.methods({
'scenarioCreate': function(scenarioObj) {
return Scenarios.insert( scenarioObj );
}
});

Meteor async call to Instagram API not returning on client side. Returns on server side

Server side:
Meteor.methods({
getFromInstagram: function(){
console.log("called!");
Future = Npm.require('fibers/future');
var myFuture = new Future();
var url = "https://api.instagram.com/v1/media/popular?access_token=[ACCESSTOKEN]";
Meteor.http.get(url, function(error, results){
if(error){
myFuture.throw(error);
} else {
myFuture.return(results);
}
});
console.log( myFuture.wait() );
return myFuture.wait();
}
});
Client side:
instagramContent = Meteor.call("getFromInstagram");
console.log(instagramContent);
The server side console log works and returns an object.
The client side console log in Chrome console returns undefined. What am I overlooking?
Client-side will always be async.
Try something like:
instagramContent = Meteor.call("getFromInstagram", function (error, result) {
console.log(result);
});
From the documentation (http://docs.meteor.com/#meteor_call):
On the client, if you do not pass a callback and you are not inside a stub, call will return undefined, and you will have no way to get the return value of the method. That is because the client doesn't have fibers, so there is not actually any way it can block on the remote execution of a method.

Block meteor helper from returning when doing http request

I need to prevent my meteor helper from returning right away until either the timeout or data returns from my Meteor.http.get(url, ...) request. For example,
Meteor.templateName.helpers ({
testHelper: function()
{
var ss = "doesnt wait";
Meteor.http.get("http://api.somesite.com",
function (error, result) {
if(!error){
if(result.statusCode === 200) {
var respJson = JSON.parse(result.content);
console.log(respJson);
ss = "should have this value";
}
}
});
return ss;
}
})
Is Meteor.http not a blocking call, how can i make the helper method stop until the get request returns data. Do i need to move the get request to a Meteor.Method ?
On the client, you don't have the fiber module, as a result is not possible to make a synchronous call to a function.
One solution might be to use a Session because of it's reactivity. You just set a default value, and use it in your helper function
Session.setDefault('testHelper', {msg: 'wait'})
Meteor.templateName.helpers ({
testHelper: function() {
return Session.get('testHelper');
}
});
Then update this session every time you want:
Template.templateName.rendered = function () {
Meteor.http.get("http://api.somesite.com",
function (error, result) {
if(!error && result.statusCode === 200){
var respJson = JSON.parse(result.content);
Session.set('testHelper', respJson)
}
}
);
}
If you don't want to use a Session, you can implement your own reactivity mecanism using the Deps module. For instance in the Meteor.http.get callback you can set a Template.templateName attribute and invalidate a context object in order to rerun the helper function. But a Session is definitly more easy ;-)

How to handle http.get() when received no data in nodejs?

Let's say that I have a service that returns customer information by a given id. If it's not found I return null.
My app calls this services like this:
http.get('http://myserver/myservice/customer/123', function(res) {
res.on('data', function(d) {
callback(null, d);
});
}).on('error', function(e) {
callback(e);
});
Currently my service responds with 200 but no data.
How do I handle when no data is returned?
Should I change it to return a different http code? In this case how to handle this? I tried many different approaches without success.
First off, it's important to remember that res is a stream of data; as it stands, your code is likely to call callback multiple times with chunks of data. (The data event is fired each time new data comes in.) If your method has been working up to this point, it's only because the responses have been small enough that the response payload wasn't broken into multiple chunks.
To make your life easier, use a library that handles buffering HTTP response bodies and allows you to get the complete response. A quick search on npm reveals the request package.
var request = require('request');
request('http://server/customer/123', function (error, response, body) {
if (!error && response.statusCode == 200) {
callback(null, body);
} else {
callback(error || response.statusCode);
}
});
As far as your service goes, if a customer ID is not found, return a 404 – it's semantically invalid to return a 200 OK when in fact there is no such customer.
Use the Client Response 'end' event:
//...
res.on('data', function(d) {
callback(null, d);
}).on('end', function() {
console.log('RESPONSE COMPLETE!');
});
I finally found a way to solve my problem:
http.get('http://myserver/myservice/customer/123', function(res) {
var data = '';
response.on('data', function(d) {
data += d;
});
response.on('end', function() {
if (data != '') {
callback(null, data);
}
else {
callback('No customer was found');
}
});
}).on('error', function(e) {
callback(e);
});
This solves the problem, but I'm also going to adopt josh3736's suggestion and return a 404 on my service when the customer is not found.

Resources