Home > front end >  Laravel Livewire/AlpineJS: Disable a button while loading data from an API and then enabling it agai
Laravel Livewire/AlpineJS: Disable a button while loading data from an API and then enabling it agai

Time:08-14

This should be really simple, but I don't get it. I want to replicate the functionality of a button that when pressed goes to an API (which could take about a minute to get the data and process it), it gets diabled, and after loading the data it gets enabled.

I'm using Laravel/Livewire/Alpine

So, in my livewire component I have:

public $loading = false;

In my blade file, I have the declaration for the div where the button is:

  <div
    
    x-data="{
      loading: @entangle('loading')
    }"
    >

Then the button x-binds the disabled property to the loading value, when the button is clicked, it changes the property of the loading variable, and calls the loader function

    <button
      type="button"
      
      x-on:click="loading = true"
      x-bind:disabled="loading"
      wire:click="loader"
      >
      Load API
    </button>

And it does what it is supposed to do... the button is grayed, it becomes unusable, the cursor change, etc., it executes the loader function in my livewire component, but it never return to the normal state after loading the API. In my livewiere componente I have:

public function loader() {
  // API call and logic goes here, this works

  $this->loading = false;
}

So I would imagine that at the end of the API process the entangled variable loading would return the button to its normal state, but it doesn't

What am I missing?

CodePudding user response:

Livewire already has incorporated functionality to handle loading-states. Instead of implementing your own, you can use this.

Get rid of all your current loading-logic, and simply use wire:loading with wire:target on your button.

wire:loading can toggle the disabled attribute directly by doing wire:loading.attr="disabled", and wire:target is to set the target for that loading-state to the method you are calling, so in your case that's wire:target="loader".

This means your button looks like this,

<button
    type="button"
    
    wire:click="loader"
    wire:loading.attr="disabled" 
    wire:target="loader"
>
    Load API
</button>
  • Related