Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: return values from http.post callback #2979

Closed
andreas83 opened this issue Dec 11, 2019 · 5 comments
Closed

Feature request: return values from http.post callback #2979

andreas83 opened this issue Dec 11, 2019 · 5 comments

Comments

@andreas83
Copy link

Missing feature

i need the return value from the http.post callback
instead http.post always returns nil, even the callback function returns a value.

Justification

Here are a real world use case for this:

function auth(user, pass)
    return http.post('https://home.io.moving-bytes.at/api/v1/login',
      'Content-Type: application/x-www-form-urlencoded\r\n',
      'username='..user..'&password='..pass,
      function(code, data)
      if (code < 0) then  
         print("HTTP request failed")
      else
         t = sjson.decode(data)
         token= t.token
         return token
      end
    end) 
    
end

function post(key, val, token)

    return http.post('https://home.io.moving-bytes.at/api/',
      'Authorization: Bearer '..token..'\r\nContent-Type: application/x-www-form-urlencoded\r\n',

      'key='..key..'&val='..val,
      function(code, data)
      if (code < 0) then  
         print("HTTP request failed")
      else
        print(data)
      end
    end)

end 

local token=auth("user", "pass");
post("key", 123, token)

Workarounds

The only possible workaround i can think of is to run the post function inside the http post callback.

@marcelstoer
Copy link
Member

This is essentially how event-driven/reactive/asynchronous programming works.

@andreas83
Copy link
Author

okay thanks for clarification, i saw there is an option in the http module on the dev-esp32 branch to switch between asynchronous and synchronous http connections.
to me it looks more feature complete, is there any chance to get it running on a ESP8266 ?

@marcelstoer
Copy link
Member

For ESP32 the Espressif ESP-IDF provides an HTTP client: https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/protocols/esp_http_client.html. The NodeMCU module is "just" a firmware API adapter.
For ESP8266 (based on NONOS SDK) there's no such thing. Our module wraps an early copy of https://github.com/Caerbannog/esphttpclient.

@andreas83
Copy link
Author

andreas83 commented Dec 15, 2019

Thanks, in case someone else also needs synchronous http requests for i.e. running dsleep after all data is send, here are my two solutions in non tested pseudo code:

Solution 1 (nested function)

        http.post(url, function(res){

            http.post(url, function(res){
                
                http.post(url, function(res){
                      //run dsleep 
                });
            
            });
        });

Solution 2 state management

Solution 2 state management

        state={[0]="init", [1]="init"}

        http.post(url, funciton(res){
            state[0]=finished;
            sleep()
        });

        http.post(url, function(res){
            state[1]=finished;
            sleep()
        });

        function sleep()
        {
            if(canWeSleep())
            {
                //run dsleep
            }
        }


        function canWeSleep()
        {
            for k, v in pairs(state) do
                if state[k]=="init" then
                    print(v)
                    return false
                end
            end
            return true;

        }

@andreas83
Copy link
Author

I worked on the state management example and tada it won't work.

Long story short, for some reasons the second time you call http.post the callback will not be called anymore!

After endless hours i found this line in the documentation

It is not possible to execute concurrent HTTP requests using this module.

Nice, so basically i can do asynchronous http request but not concurrent...

Related tickets are here #1293 #1258 and #1629

Please could you fix this somehow?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants