Specific Loading target

Hi all,

I use the wire:loading in a table with the targets of “reOpen” and “close”. In these methods I pass an ID.

<button class="btn btn-sm btn-outline-secondary"  
		title="Re-open ticket"
		wire:click="reOpen('{{ $ticket->ticket_id }}')"
		wire:loading.attr="disabled"
		wire:loading.class="loading-hide"
>
	<i class="fas fa-undo"></i>
</button>

<button wire:loading 
	    wire:target="reOpen" 
	    class="btn btn-sm btn-primary" 
	    type="button" disabled
>
	<span class="spinner-grow spinner-grow-sm" role="status" aria-hidden="true"></span>
</button>

This works like magic, but when I click on the button that calls the reOpen method, the loading button shows on all other elements. I’ve tried to target reOpen('{{ $ticket->ticket_id }}') and set unique wire:key as well as id on each button, but the loading button not showing.

Is there a way that the loading button can target by wire:key or only method?

Thank you

1 Like

There isn’t anything in the docs that covers this use case. Any loading that targets a method in the same component is going to get triggered.

Extract those methods into a component that handles each table row. The loading will only target the one on that table row because it will be contained within it’s own component. I think a good rule of thumb is anytime you have a call to a method in a loop, it should be extracted to it’s own component. That also avoids you from mustaching parameters into the method that could be tampered with.

Hi @stefanbauer ,

Thanks for the link, but I doubt you understood what is the problem here.

Thank you @xxdalexx,
The individual component makes sense. I haven’t tried it yet, but I don’t see why it wouldn’t work.
Shame I haven’t thought about this.

Thanks again.

@xxdalexx,
I just got to it and while started to create the child components it got me thinking, that this should work as I said your suggestion completely makes sense, although it doesn’t feel natural.
I got to the habbit while I’m developing if something doesn’t feel “natural” I must improve on the implementation. I think it would be a very nice addition to the wire:loading attribute to target a specific id. This, of course would happen mainly in tr, li elements, but it would be handy in any case really.
Although I like smaller chunks of codes (components), but there is a line where I prefer to just have that couple of lines of code in the “parent”. The reason for this is that it is more readable when it is only few lines.

I hope or I’m sure you get what I mean. please don’t take this as a moaning!! I’m only try to suggest good stuff to livewire that would push this package further.
I’m not going to tag Caleb as I’m sure he is busy as hell, but I am happy to whip up some use cases with explanations. I would LOVE to implement it, but I’m afraid my knowledge is nowhere near required to do it.

Thanks

I think it would be a great addition to the api to have increased control over loading targeting, I don’t disagree with you on that point at all. When I respond to issues here, I try to find how to achieve the intended result within the tool set currently available.

I will however argue and expand on my point earlier against mustaching method parameters (going outside of the original scope of this thread), and I guess argue the “natural” feeling of it. I’m also not targeting you individually, nothing personal, I’m putting it out there for anyone who reads through this so everyone can see the possible implications of this, or just have a better understanding of how it works and your options.

wire:click="method('{{ $variable }}')"
feels incredibly unnatural to me vs
wire:click="method"

Livewire does no tampering validation on anything inside of those method brackets. Open your inspector and change it to whatever you want. Almost every post on here, including this one, that makes use of it is always passing some sort of a database id. (My opinion, and many other’s, is id’s should never be exposed to the front end to begin with, that’s what slugs are for. but that’s another debate)

I also don’t care to have brackets there, even empty, because someone who knows a thing or two about programming, but not how livewire works, is automatically tipped off that it’s referencing a method/function. It’s not that big of a deal, but it’s a bigger invitation for someone to try to tamper with it just to see what happens.

Yes, you can protect yourself by adding in additional validation before a database call is made. Or you can extract it to it’s own component, store the model internally, and not even accept a parameter to be passed in to begin with.

One of the trade offs to using liveware is that the id will still be exposed to the front end even going this route. In your console, it can be found livewire.components.componentsById.{componentId}.data.{model}.id However, Livewire does have tamper protection on it. If you change it and then try to make another request you will get:

"Livewire encountered corrupt data when trying to hydrate the [componentName] component. Ensure that the [name, id, data] of the Livewire component wasn’t tampered with between requests. "

You could even take it one step further and use the session to store your model and never pass it to the front.

TL:DR: Life is easier when you limit possible security concerns. Don’t mustache a method parameter you wouldn’t offer an input box to for the user to change.

1 Like