Set timeout for http post

I’m trying to set a timeout for my http POST where if the time is over and i don’t get the data, i’ll display a message.
This is what i’m doing:

this.http.post('myUrl', 
    MyData, {headers: Myheaders})
        .timeout(10000)
        .map(res => res.json())
        .subscribe(
            data => this.ret = data,
            error => console.log('ERROR'),
            () => console.log('END')
        );

The problem is that i see my output ‘ERROR’ in my console not after 10 seconds but instantly so the timeout is not working…

How can i make it work?

Thanks to all :slight_smile:

Do you have sure that it will generate a timeout error?
You need to simulate a timeout on your server to test. For example on PHP:

sleep(10);

This way the server will wait 10 seconds to complete your request.

Maybe your error is caused by another situation, and not for timeout.

That error is triggered when there is no connection so the app can’t get the data from my server.
So i simulate this taking off the connection before the http post.
But it doesn’t wait for 10 seconds before to show the error (i.e. waiting data untill 10 seconds before to go to error), instead the error is showed instantly.
Any ideas for this common problem?

I think the problem is your simulation method isn’t valid. The timeout function wouldn’t trigger if there’s no connection to be made, that’s a completely different error unrelated to timeouts.

Thank you for the reply, how do you suggest to try to get data for like 10 seconds and then return an error if it’s not arrived?

as @diegomachado said above - inject a deliberate server-side delay. Or connect to a wifi signal that has no access to the server, but the device still maintains a connection.

Ok this will handle the case where the server is giving the response too late.
But what i’m trying to do is also to handle the real case where the server is working as usual but the device doensn’t have the connection.
How to resolve this second situation to keep my device trying for a certain amount of time a http post using the timeout?
Thank you for the support @beck24

You can deal with it in the error handler, or if you want to be proactive you can use the network connection plugin and detect the connection status: http://ionicframework.com/docs/native/network/

I had a problem with timeout too, if I reckon correctly, to solve my problem I just had to import the following (which I had forgot):

import 'rxjs/add/operator/timeout';

Maybe same problem for you…

For example this work for me (if I don’t forget the above import :wink: )

this.http.post('http://stuffs.com',
            body, {headers: headers})
            .timeout(10000)
            .map(res => res.json())
            .subscribe((something: any) => {
                // Do stuffs
            }, (errorResponse: any) => {
                // Don't do stuffs
            });

I’m trying your first advice, “You can deal with it in the error handler”, i.e. what i was trying to do at my first post but i can’t figure out how because i’m still getting the part console.log('ERROR') not after the time i set in .timeout(10000) but instantly.
This is my code now:

Service

 myMethod() {
    return this.http.post(myurl, mymessage, myoptions)
      .timeout(10000)
     .map(data=> {
          return this.secondMethod(data);
        })
      }

My .ts file:

this.myService.myMethod()
      .subscribe(
      data => {
     //not the important part
      },
      error => console.log('ERROR', error),
      () => console.log('END')
      )

@reedrichards Thank you for trying to help, but i have already setted that.

I’m probably missing something really important/basilar thing because i think everyone did this or a similar thing in each own app.

1 Like

@LemanSan just to be sure, so you are confirming that you are importing

import 'rxjs/add/operator/timeout';

right?

then sorry that that didn’t solve your issue, for my part I really don’t do more than what I display above

@reedrichards Yes i have import 'rxjs/add/operator/timeout'; on my service.

So with the last code you showed (where i don’t see something different from mine) if you take off the connection, then do the api call, it will wait 10 seconds before the "// Don't do stuffs" will be executed?

Please tell me no because i don’t know what to do if you say yes :sweat_smile:

yes, I’m pretty sure :frowning:

when I debug locally my server, I always land in the // Don't do stuffs because I stay too long on my breakpoints :wink:

I use angular 4.1.3, what about you?

ionic-angular 3.4.2
It could be the problem? Ionic doesn’t say to me to update it…

I think it changed from 3 to 4 … let me check my history

1 Like

Actually maybe no, it changed when I upgraded from @ionic/app-scripts 1.0.0 to 1.1.3

Anyway, so before this upgrade it worked like following (see new Error…):

 this.http.post('http://stuffs.com',
        body, {headers: headers})
        .timeout(10000, new Error('Login timeout exceeded'))
        .map(res => res.json())
        .subscribe((something: any) => {
            // Do stuffs
        }, (errorResponse: any) => {
            // Don't do stuffs
        });

Also I noticed, in my example, i don’t have the following code in my subscribe…maybe give a try without it?

 () => console.log('END')

Already tried without () => console.log('END') and nothing changed.
Adding .timeout(10000, new Error('Login timeout exceeded')) i get a compile error:

Argument of type 'Error' is not assignable to parameter of type 'IScheduler'. Property 'now' is missing in type 'Error' so i thought it's no more possible to pass a string like that.

I have @ionic/app-scripts : 1.3.7 and no ideas on how to solve this in this moment.

:frowning:

Well I’m out of idea too … last thing maybe, you are importing map too?

 import 'rxjs/add/operator/map';

Don’t know if that could help

Yes i already have it on my service. :roll_eyes:

I’ll keep following this thread anyway, thanks.

1 Like