Data Properties

Livewire components store and track data as public properties on the component class.

class HelloWorld extends Component
{
    public $message = 'Hello World!';
    ...

Public properties in Livewire are automatically made available to the view. No need to explicitly pass them into the view (although you can if you want).

use Livewire\Component;

class HelloWorld extends Component
{
    public $message = 'Hello World!';

    public function render()
    {
        return view('livewire.hello-world');
    }
}
<div>
    <h1>{{ $message }}</h1>
    <!-- Will output "Hello World!" -->
</div>

First, Three Important Notes

Here are three ESSENTIAL things to note about public properties before embarking on your Livewire journey:

  1. Data stored in public properties is made visible to the front-end JavaScript. Therefore, you SHOULD NOT store sensitive data in them.
  2. Properties can ONLY be either a JavaScript-friendly data types (string, int, array, boolean), OR an eloquent model (or collection of models).

For more information on storing sensitive data in your Livewire components or storing different data types in them, see this guide (replace me!!!)

protected and private properties DO NOT persist between Livewire updates. In general, you should avoid using them for storing state.

Initializing Properties

You can initialize properties using the mount method of your component.

use Livewire\Component;

class HelloWorld extends Component
{
    public $message;

    public function mount()
    {
        $this->message = 'Hello World!';
    }

    public function render()
    {
        return view('livewire.hello-world');
    }
}

Livewire also makes a $this->fill() method available to you for cases where you have to set lots of properties and want to remove visual noise.

public function mount()
{
    $this->fill(['message' => 'Hello World!']);
}

Additionally, Livewire offers $this->reset() to programatically reset public property values to their initial state. This is useful for cleaning input fields after performing an action.

public $name = '';

public function savePost()
{
    $this->post->update([
        'name' => $this->name,
    ]);

    $this->reset();
    // Will reset all public properties.

    $this->reset('name');
    // Will only reset the name property.
}

Data Binding

If you've used front-end frameworks like Vue, or Angular, you are already familiar with this concept. However, if you are new to this concept, Livewire can "bind" (or "synchronize") the current value of some HTML element with a specific property in your component.

use Livewire\Component;

class HelloWorld extends Component
{
    public $message;

    public function render()
    {
        return view('livewire.hello-world');
    }
}
<div>
    <input wire:model="message" type="text">

    <h1>{{ $message }}</h1>
</div>

When the user types something into the text field, the value of the $message property will automatically update.

Internally, Livewire will listen for an input event on the element, and when triggered, it will send an AJAX request to re-render the component with the new data.

You can add wire:model to any element that dispataches an input event. Even custom elements, or third-party JavaScript libraries.

Common elements to use wire:model on include:

Element Tag
<input type="text">
<input type="radio">
<input type="checkbox">
<select>
<textarea>

Input Debounce

By default, Livewire applies a 150ms debounce to text inputs. This avoids too many network requests being sent as a user types into a text field.

If you wish to override this default (or add it to a non-text input), Livewire offers a "debounce" modifier. If you want to apply a half-second debounce to an input, you would include the modifier like so:

<input type="text" wire:model.debounce.500ms="name">

Nested Data

Livewire supports binding to nested data inside arrays using dot notation:

<input type="text" wire:model="parent.message">

Lazily Updating

By default, Livewire sends a request to server after every input event (or change in some cases). This is usually fine for things like <select> elements that don't typically fire rapid updates, however, this is often unnecessary for text fields that update as the user types.

In those cases, use the lazy directive modifier to listen for the native "change" event.

<input type="text" wire:model.lazy="message">

Now, the $message property will only be updated when the user clicks away from the input field.

Updating The Query String

Sometimes it's useful to update the browser's query string when your component state changes.

For example, if you were building a "search posts" component, and wanted the query string to reflect the current search value like so:

https://your-app.com/search-posts?search=some-search-string

This way, when a user hits the back button, or bookmarks the page, you can get the initial state out of the query string, rather than resetting the component every time.

In these cases, you can add a property's name to protected $updatesQueryString, and Livewire will update the query string every time the property value changes.

use Livewire\Component;

class SearchPosts extends Component
{
    public $search;

    protected $updatesQueryString = ['search'];

    public function mount()
    {
        $this->search = request()->query('search', $this->search);
    }

    public function render()
    {
        return view('livewire.search-posts', [
            'posts' => Post::where('title', 'like', '%'.$this->search.'%')->get(),
        ]);
    }
}
<div>
    <input wire:model="search" type="text" placeholder="Search posts by title...">

    <h1>Search Results:</h1>

    <ul>
        @foreach($posts as $post)
            <li>{{ $post->title }}</li>
        @endforeach
    </ul>
</div>

Keeping A Clean Query String

In the case above, when the search property is empty, the query string will look like this:

?search=

There are other cases where you might want to only represent a value in the query string if it is NOT the default setting.

For example, if you have a $page property to track pagination in a component, you may want to remove the page property from the query string when the user is on the first page.

In cases like these, you can use the following syntax:

use Livewire\Component;

class SearchPosts extends Component
{
    public $foo;
    public $search = '';
    public $page = 1;

    protected $updatesQueryString = [
        'foo',
        ['search' => ['except' => '']],
        ['page' => ['except' => 1]],
    ];

    public function mount()
    {
        $this->fill(request()->only('search', 'page'));
    }

    ...
}

Casting Properties

Livewire offers an api to "cast" public properties to a more usable data type. Two common use-cases for this are working with date objects like Carbon instances, and dealing with Laravel collections:

class CastedComponent extends Component
{
    public $options = ['foo', 'bar', 'bar'];
    public $expiresAt = 'tomorrow';
    public $formattedDate = 'today';

    protected $casts = [
        'options' => 'collection',
        'expiresAt' => 'date',
        'formattedDate' => 'date:m-d-y'
    ];

    public function getUniqueOptions()
    {
        return $this->options->unique();
    }

    public function getExpirationDateForHumans()
    {
        return $this->expiresAt->format('m/d/Y');
    }

    ...

Custom Casters

Livewire allows you to build your own custom casters for custom use-cases. Implement the Livewire\Castable interface in a class and reference it in the $casts property:

class FooComponent extends Component
{
    public $foo = ['bar', 'baz'];

    protected $casts = ['foo' => CollectionCaster::class];

    ...
use Livewire\Castable;

class CollectionCaster implements Castable
{
    public function cast($value)
    {
        return collect($value);
    }

    public function uncast($value)
    {
        return $value->all();
    }
}

Computed Properties

Livewire offers an api for accessing dynamic properties. This is especially helpful for deriving properties from the database or another persistent store like a cache.

class ShowPost extends Component
{
    // Computed Property
    public function getPostProperty()
    {
        return Post::find($this->postId);
    }

Now, you can access $this->post from either the component's class or Blade view:

use Livewire\Component;

class ShowPost extends Component
{
    public $postId;

    public function mount($postId)
    {
        $this->postId = $postId;
    }

    public function getPostProperty()
    {
        return Post::find($this->postId);
    }

    public function deletePost()
    {
        $this->post->delete();
    }

    public function render()
    {
        return view('livewire.show-post');
    }
}
<div>
    <h1>{{ $this->post->title }}</h1>
    ...
    <button wire:click="deletePost">Delete Post</button>
</div>
Computed properties are cached for an individual Livewire request lifecycle. Meaning, if you call `$this->post` 5 times in a component's blade view, it won't make a seperate database query every time.
← Previous Topic

The mount() Method

Next Topic →

Actions

Laravel Intellow Cierra 1043 Labs JR Merritt Trustfactory