⚠️ This lesson is retired and might contain outdated information.

Disable Buttons While Data is Loading with RxJS and Vue.js

John Lindquist
InstructorJohn Lindquist
Share this video with your friends

Social Share Links

Send Tweet
Published 7 years ago
Updated 9 months ago

Streams give you the power to handle a "pending" state where you've made a request for data, but the data hasn't yet returned. You can leverage this pending stream to update your template as well which is often displayed as a "loader" or disabling some part of the UI.

Instructor: [00:00] If we click really quickly, you can see this request being made over and over and over again, even if we click before the data has loaded. We can disable this button while the data is loading by creating a disable stream based on this click stream and the Luke stream, essentially, we'll say that our disable stream is a combination or an observable merge of the clicks of the stock click, and when the Luke stream is ready.

[00:31] When a value gets pushed through here or a value gets pushed through here. When a value gets pushed through from click, we'll map it to true, and when a value gets pushed through Luke and is done with the stream, we'll map to false.

[00:46] Then, we can return the stream in our object here "disabled." And then, I'm gonna put that on the disabled property or the button, we'll bind disabled to our disabled stream. To make this more obvious, I'm going to come into the performance tab, go into my settings and change the network to slow 3G.

[01:10] When I click on that button, you'll notice it goes disabled until the data is done loading. I'll do that now. You could see grays out, and then the day comes in and then it's enabled again. If you look at the network, I'll clear this out, I'll click and you'll see the request go out and the response come back, and then the button re-enables.

[01:30] Disabled response comes back enabled. Now we can make this more apparent, a button text stream based on our disabled stream. I'll say button text is our disabled stream mapped to, and we'll just have a boolean value here.

[01:49] If this is true, if it is disabled, we'll say it's loading. And if it's false, we'll say load. Then, we can return our button text down in our object here button text and use our button text inside of our button.

[02:11] You'll notice right now, there is no text in the button, but I'll click it and you'll see it turns to loading and then now it's back at load. Click again, turns to loading and goes to load.

[02:22] To fix that empty text at the beginning, I'll go back down to my button text stream and I'll tell it to start with false, hit save, and now, you see the text defaults to load because false comes through right away.

[02:38] I'll click changes to loading and goes back to load. Now, because we're basing this button text on the disabled stream, it probably makes more sense to grab this start with and move it up to the disabled stream. In case anything else relies on the disabled stream, they'll all stay in sync there.

[02:55] Hit save now and get that same result. Now, it says load at the beginning because our disabled stream is starting with false and pushing that value through so that our button text handles that first false, and gives us load and right click goes to loading and it's done and shows load.

Paul Perry
Paul Perry
~ 6 years ago

For rxjs 6 users, imports only need the startWith adding to the imports from rxjs/operators, but updated for clarity:

import { from, merge, of } from 'rxjs'
import { pluck, switchMap, map, mapTo, catchError, share, startWith } from 'rxjs/operators'

Then, just for good measure, here're the updated disabled and buttonText streams, using pipe:

    const disabled$ = merge(
      this.click$.pipe(mapTo(true)),
      getName$.pipe(mapTo(false))
    ).pipe(
      startWith(false)
    )
    
    const buttonText$ = disabled$.pipe(
      map(bool => bool ? "Loading..." : "Load" )
    )

I hope nobody minds I'm adding these below each video, and that they help someone!

Markdown supported.
Become a member to join the discussionEnroll Today