How can I delay an observable only if it returns faster than the delay





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







1















Take for example:



 this.http.get('/getdata').pipe(delay(2000))


I would like this request to take a minimum of 2s to complete, but not any longer than it takes for the request to complete.



In other words:




  1. if the request takes 1s to complete, I want the observable to complete in 2s.


  2. if the request takes 3s to complete, I want the observable to complete in 3s NOT 5s.



Is there some other pipe other than delay() that can achieve this that I don't know about or is there a way to build a custom pipe for this if necessary?



The use case is to show a loader, however if the request completes too fast it doesnt look good when the loader just "flashes" for a split second










share|improve this question

























  • Consider a better solution from a UX perspective. Only show the loader after a short duration if the request has not yet returned. That means that if the request returns fast, no loader is necessary at all.

    – GregL
    Jan 3 at 22:39






  • 1





    @GregL that just moves the same problem. If the request takes only slightly longer than the short duration, the loader appears then disappears again immediately.

    – jonrsharpe
    Jan 3 at 22:41






  • 1





    Why not move this logic to the loader? It gets shown when the request starts, then told to go when the request ends, and it's up to it to decide whether it needs to pause before disappearing to avoid the flickering effect. It seems weird to deliberately delay the actual data and processing, rather than just the display.

    – jonrsharpe
    Jan 3 at 22:43













  • @jonrsharpe You are always going to have a case where the loader is shown inconveniently just before the response returns. It's about reducing the likelihood of that happening by omitting the spinner for users where a response is returned prior to the user thinking the UI is nonresponsive (which is the purpose of a loader, to show you that something is happening).

    – GregL
    Jan 3 at 22:48













  • That said, there is valid use cases for deliberately delaying updating the UI, even if the response is fast. There are certain operations we have been conditioned to believe take some noticeable period of time. If they instead appear to happen instantly, people distrust the system and believe it was too fast to be real.

    – GregL
    Jan 3 at 22:50


















1















Take for example:



 this.http.get('/getdata').pipe(delay(2000))


I would like this request to take a minimum of 2s to complete, but not any longer than it takes for the request to complete.



In other words:




  1. if the request takes 1s to complete, I want the observable to complete in 2s.


  2. if the request takes 3s to complete, I want the observable to complete in 3s NOT 5s.



Is there some other pipe other than delay() that can achieve this that I don't know about or is there a way to build a custom pipe for this if necessary?



The use case is to show a loader, however if the request completes too fast it doesnt look good when the loader just "flashes" for a split second










share|improve this question

























  • Consider a better solution from a UX perspective. Only show the loader after a short duration if the request has not yet returned. That means that if the request returns fast, no loader is necessary at all.

    – GregL
    Jan 3 at 22:39






  • 1





    @GregL that just moves the same problem. If the request takes only slightly longer than the short duration, the loader appears then disappears again immediately.

    – jonrsharpe
    Jan 3 at 22:41






  • 1





    Why not move this logic to the loader? It gets shown when the request starts, then told to go when the request ends, and it's up to it to decide whether it needs to pause before disappearing to avoid the flickering effect. It seems weird to deliberately delay the actual data and processing, rather than just the display.

    – jonrsharpe
    Jan 3 at 22:43













  • @jonrsharpe You are always going to have a case where the loader is shown inconveniently just before the response returns. It's about reducing the likelihood of that happening by omitting the spinner for users where a response is returned prior to the user thinking the UI is nonresponsive (which is the purpose of a loader, to show you that something is happening).

    – GregL
    Jan 3 at 22:48













  • That said, there is valid use cases for deliberately delaying updating the UI, even if the response is fast. There are certain operations we have been conditioned to believe take some noticeable period of time. If they instead appear to happen instantly, people distrust the system and believe it was too fast to be real.

    – GregL
    Jan 3 at 22:50














1












1








1








Take for example:



 this.http.get('/getdata').pipe(delay(2000))


I would like this request to take a minimum of 2s to complete, but not any longer than it takes for the request to complete.



In other words:




  1. if the request takes 1s to complete, I want the observable to complete in 2s.


  2. if the request takes 3s to complete, I want the observable to complete in 3s NOT 5s.



Is there some other pipe other than delay() that can achieve this that I don't know about or is there a way to build a custom pipe for this if necessary?



The use case is to show a loader, however if the request completes too fast it doesnt look good when the loader just "flashes" for a split second










share|improve this question
















Take for example:



 this.http.get('/getdata').pipe(delay(2000))


I would like this request to take a minimum of 2s to complete, but not any longer than it takes for the request to complete.



In other words:




  1. if the request takes 1s to complete, I want the observable to complete in 2s.


  2. if the request takes 3s to complete, I want the observable to complete in 3s NOT 5s.



Is there some other pipe other than delay() that can achieve this that I don't know about or is there a way to build a custom pipe for this if necessary?



The use case is to show a loader, however if the request completes too fast it doesnt look good when the loader just "flashes" for a split second







rxjs rxjs6 rxjs-pipeable-operators






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 3 at 22:39









jonrsharpe

78.9k11110222




78.9k11110222










asked Jan 3 at 22:33









parliamentparliament

14k27117197




14k27117197













  • Consider a better solution from a UX perspective. Only show the loader after a short duration if the request has not yet returned. That means that if the request returns fast, no loader is necessary at all.

    – GregL
    Jan 3 at 22:39






  • 1





    @GregL that just moves the same problem. If the request takes only slightly longer than the short duration, the loader appears then disappears again immediately.

    – jonrsharpe
    Jan 3 at 22:41






  • 1





    Why not move this logic to the loader? It gets shown when the request starts, then told to go when the request ends, and it's up to it to decide whether it needs to pause before disappearing to avoid the flickering effect. It seems weird to deliberately delay the actual data and processing, rather than just the display.

    – jonrsharpe
    Jan 3 at 22:43













  • @jonrsharpe You are always going to have a case where the loader is shown inconveniently just before the response returns. It's about reducing the likelihood of that happening by omitting the spinner for users where a response is returned prior to the user thinking the UI is nonresponsive (which is the purpose of a loader, to show you that something is happening).

    – GregL
    Jan 3 at 22:48













  • That said, there is valid use cases for deliberately delaying updating the UI, even if the response is fast. There are certain operations we have been conditioned to believe take some noticeable period of time. If they instead appear to happen instantly, people distrust the system and believe it was too fast to be real.

    – GregL
    Jan 3 at 22:50



















  • Consider a better solution from a UX perspective. Only show the loader after a short duration if the request has not yet returned. That means that if the request returns fast, no loader is necessary at all.

    – GregL
    Jan 3 at 22:39






  • 1





    @GregL that just moves the same problem. If the request takes only slightly longer than the short duration, the loader appears then disappears again immediately.

    – jonrsharpe
    Jan 3 at 22:41






  • 1





    Why not move this logic to the loader? It gets shown when the request starts, then told to go when the request ends, and it's up to it to decide whether it needs to pause before disappearing to avoid the flickering effect. It seems weird to deliberately delay the actual data and processing, rather than just the display.

    – jonrsharpe
    Jan 3 at 22:43













  • @jonrsharpe You are always going to have a case where the loader is shown inconveniently just before the response returns. It's about reducing the likelihood of that happening by omitting the spinner for users where a response is returned prior to the user thinking the UI is nonresponsive (which is the purpose of a loader, to show you that something is happening).

    – GregL
    Jan 3 at 22:48













  • That said, there is valid use cases for deliberately delaying updating the UI, even if the response is fast. There are certain operations we have been conditioned to believe take some noticeable period of time. If they instead appear to happen instantly, people distrust the system and believe it was too fast to be real.

    – GregL
    Jan 3 at 22:50

















Consider a better solution from a UX perspective. Only show the loader after a short duration if the request has not yet returned. That means that if the request returns fast, no loader is necessary at all.

– GregL
Jan 3 at 22:39





Consider a better solution from a UX perspective. Only show the loader after a short duration if the request has not yet returned. That means that if the request returns fast, no loader is necessary at all.

– GregL
Jan 3 at 22:39




1




1





@GregL that just moves the same problem. If the request takes only slightly longer than the short duration, the loader appears then disappears again immediately.

– jonrsharpe
Jan 3 at 22:41





@GregL that just moves the same problem. If the request takes only slightly longer than the short duration, the loader appears then disappears again immediately.

– jonrsharpe
Jan 3 at 22:41




1




1





Why not move this logic to the loader? It gets shown when the request starts, then told to go when the request ends, and it's up to it to decide whether it needs to pause before disappearing to avoid the flickering effect. It seems weird to deliberately delay the actual data and processing, rather than just the display.

– jonrsharpe
Jan 3 at 22:43







Why not move this logic to the loader? It gets shown when the request starts, then told to go when the request ends, and it's up to it to decide whether it needs to pause before disappearing to avoid the flickering effect. It seems weird to deliberately delay the actual data and processing, rather than just the display.

– jonrsharpe
Jan 3 at 22:43















@jonrsharpe You are always going to have a case where the loader is shown inconveniently just before the response returns. It's about reducing the likelihood of that happening by omitting the spinner for users where a response is returned prior to the user thinking the UI is nonresponsive (which is the purpose of a loader, to show you that something is happening).

– GregL
Jan 3 at 22:48







@jonrsharpe You are always going to have a case where the loader is shown inconveniently just before the response returns. It's about reducing the likelihood of that happening by omitting the spinner for users where a response is returned prior to the user thinking the UI is nonresponsive (which is the purpose of a loader, to show you that something is happening).

– GregL
Jan 3 at 22:48















That said, there is valid use cases for deliberately delaying updating the UI, even if the response is fast. There are certain operations we have been conditioned to believe take some noticeable period of time. If they instead appear to happen instantly, people distrust the system and believe it was too fast to be real.

– GregL
Jan 3 at 22:50





That said, there is valid use cases for deliberately delaying updating the UI, even if the response is fast. There are certain operations we have been conditioned to believe take some noticeable period of time. If they instead appear to happen instantly, people distrust the system and believe it was too fast to be real.

– GregL
Jan 3 at 22:50












1 Answer
1






active

oldest

votes


















1














To answer the question as asked, you could simply use combineLatest() to combine a timer(2000) observable and the request observable, then just ignore the result from the timer observable. It works because combineLatest waits until all observables have emitted at least one value before emitting one itself.



combineLatest(this.http.get('/getdata'), timer(2000), x => x)





share|improve this answer
























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54030722%2fhow-can-i-delay-an-observable-only-if-it-returns-faster-than-the-delay%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    To answer the question as asked, you could simply use combineLatest() to combine a timer(2000) observable and the request observable, then just ignore the result from the timer observable. It works because combineLatest waits until all observables have emitted at least one value before emitting one itself.



    combineLatest(this.http.get('/getdata'), timer(2000), x => x)





    share|improve this answer




























      1














      To answer the question as asked, you could simply use combineLatest() to combine a timer(2000) observable and the request observable, then just ignore the result from the timer observable. It works because combineLatest waits until all observables have emitted at least one value before emitting one itself.



      combineLatest(this.http.get('/getdata'), timer(2000), x => x)





      share|improve this answer


























        1












        1








        1







        To answer the question as asked, you could simply use combineLatest() to combine a timer(2000) observable and the request observable, then just ignore the result from the timer observable. It works because combineLatest waits until all observables have emitted at least one value before emitting one itself.



        combineLatest(this.http.get('/getdata'), timer(2000), x => x)





        share|improve this answer













        To answer the question as asked, you could simply use combineLatest() to combine a timer(2000) observable and the request observable, then just ignore the result from the timer observable. It works because combineLatest waits until all observables have emitted at least one value before emitting one itself.



        combineLatest(this.http.get('/getdata'), timer(2000), x => x)






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 3 at 23:00









        GregLGregL

        24.6k55158




        24.6k55158
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54030722%2fhow-can-i-delay-an-observable-only-if-it-returns-faster-than-the-delay%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Monofisismo

            Angular Downloading a file using contenturl with Basic Authentication

            Olmecas