I don't understand why HTTP.get function isn't working


#1

What works easily in python using requests module, doesn’t work in my meteor app using http package.

j@j-desktop:~/_Github-Projects/inventory_synchronize$ python3
Python 3.5.2 (default, Nov 23 2017, 16:37:01) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> requests.get('http://jsonplaceholder.typicode.com/posts').text

in my meteor app, inside the file inventory_synchronize/server/main.js, I have

Meteor.methods({
  insertInvFromEbayJson() {
      let response = HTTP.get('http://jsonplaceholder.typicode.com/posts');
      return response.content;
  }
});

The exception I’m getting is
Exception while invoking method 'insertInvFromEbayJson' ReferenceError: reponse is not defined

I understand that I’m using the function get, synchronously, so the execution should block until the request returns a response there which is fine in this context and my testing.


#2

I think what might be happening is that you are seeing the result of this code being run on the client. You’ll need to move the method definition to server only code.


#3

I thought files in $PROJECT_ROOT/server/ dir were all server files?


#4

That’s correct. If the method definition isn’t loaded and running on the client, then I can’t think of an explanation for this error.


#5

No. This is an asynchronous method. What happens is the follows:

a) The HTTP request is called
b) The function returns before the request is resolved.

The HTTP function does not return the result of the request if you call it naively in this way.

You have two options: Either work with the callback function like so:

HTTP.get("/foo", {payloadObject}, (err, result) => {
   //process result
});

or you learn a bit about async / await and use that.

Read the docs a bit, please.


#6

HTTP.get runs sync on the server


#7

Thanks, you helped fix it. I actually don’t need to have the method return anything so I can just update the db from within the server sided method.

updated server/main.js file contents:

  Meteor.methods({
    insertInvFromEbayJson(filePath) {
      if (canViewInventory(this.userId)) {
        console.log('file', filePath);
  
        HTTP.get(
          url=filePath,
          asyncCallback=(err, response) => {
            if (err) throw err;
            console.log(response.content);
        });
      } else {
        console.warn('you do not have permission to insert into this db');
      }
    }
  });

imports/ui/App.js

// in some file upload callback method
              Meteor.call('insertInvFromEbayJson', downloadUrl));

#8

You still need the callback. If you want a result, that is.


#9

Incorrect. On the server you can use sync-style exactly like that.


#10

Obviously not if his code bombs out like he just described…


#11

Just read the docs. I use it like that all the time. I’ve never used the callback form on the server.


#12

One more reason why I like C# better than this. Silently converting async stuff into sync stuff is quite nasty.

Still doesn’t explain why his code fails.


#13

Well, what I would do is wrap the (original) HTTP request in a try/catch and report the error.