Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

janmoes's avatar

Livewire not updating a value

Hey there guys,

I've recently made a component in Livewire for the first time. I didn't include it within a view, I load it in through a route instead. The basic thing is that I've made an increment and decrement method, They should update $page_number, but nothing seems to happen.

Here's the view that the component renders:

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-10">
            <div class="card">
                <div class="card-header">{{ __('Dashboard') }}</div>

                <div class="card-body">
                    <h2 class="text-center">Domeinen</h2>
                    <div class="table-responsive">
                        <table class="table">
                            <thead>
                                <tr>
                                    <th scope="col">ID</th>
                                    <th scope="col">Naam</th>
                                    <th scope="col">Opties</th>
                                </tr>
                            </thead>
                            <tbody>
                                @foreach($domains as $domain)
                                <tr>
                                    <th scope="row">{{$domain->id}}</th>
                                    <td>{{$domain->url}}</td>
                                    <td><a href="{{ route('domains.show', $domain->id) }}" class="btn btn-primary btn-font"><i class="fa fa-globe"></i> Bekijk domein details</a></td>
                                </tr>
                                @endforeach
                            </tbody>
                        </table>
                    </div>
                    <div>
                        <span>{{$page_number}}</span>
                        <button wire:click="decrement">-</button>
                        <button wire:click="increment">+</button>
                    </div>
                    <a href="{{ route('home') }}" class="btn btn-warning"><i class="fa fa-arrow-left"></i> Terug naar het dashboard</a>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

And here's the Component:

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use Illuminate\Support\Facades\Http;

class DomainList extends Component
{
    public $base_url = 'https://my.gridpane.com/oauth/api/v1/site?page=';
    public $page_number = 1;
    public $domains = [];
    public $first_page;
    public $last_page;
    public $prev = true;
    public $next = true;

    public function mount(){
        $response = Http::withOptions([ //use this method
            'verify'     => false, //This key and value in this method
        ])->withHeaders([
            'Content-Type'  => 'application/json',
            'Accept'        => 'application/json',
            'Authorization' => 'Bearer '.env('TOKEN'),
            'data-raw'      =>  [
                'summary' => true,
            ],
        ])->get($this->base_url.$this->page_number);
        
        $this->first_page = $response['links']['first'];
        $this->last_page = $response['links']['last'];
        $this->domains = collect($response['data'])->map(fn($site) => (object) $site);
    }

    public function increment(){
        $this->page_number++;
        // dd($this->page_number);
    }

    public function decrement(){
        $this->page_number--;
    }

    public function render()
    {
        return view('livewire.domain-list');
    }
}

I've read in the docs and looked it up and you need to apply an empty div around your code like it's a template. But I'd like to include the main styling of my website.

0 likes
29 replies
chaudigv's avatar

You can configure Livewire to reference it using ->extends()

return view('livewire.domain-list')
    ->extends('layouts.app');

That way, you only need one parent tag with deafult @yield('content') so you don't need to specify it in the livewire blade component.

<div class="container">
.
.
</div>
janmoes's avatar

@chaudigv Thanks for the reply! I've added the extending to the view render, and changed the view from the component to this:

<div>
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-10">
            <div class="card">
                <div class="card-header">{{ __('Dashboard') }}</div>

                <div class="card-body">
                    <h2 class="text-center">Domeinen</h2>
                    <div class="table-responsive">
                        <table class="table">
                            <thead>
                                <tr>
                                    <th scope="col">ID</th>
                                    <th scope="col">Naam</th>
                                    <th scope="col">Opties</th>
                                </tr>
                            </thead>
                            <tbody>
                                @foreach($domains as $domain)
                                <tr>
                                    <th scope="row">{{$domain->id}}</th>
                                    <td>{{$domain->url}}</td>
                                    <td><a href="{{ route('domains.show', $domain->id) }}" class="btn btn-primary btn-font"><i class="fa fa-globe"></i> Bekijk domein details</a></td>
                                </tr>
                                @endforeach
                            </tbody>
                        </table>
                    </div>
                    <div>
                        <span>{{$page_number}}</span>
                        <button wire:click="decrement">-</button>
                        <button wire:click="increment">+</button>
                    </div>
                    <a href="{{ route('home') }}" class="btn btn-warning"><i class="fa fa-arrow-left"></i> Terug naar het dashboard</a>
                </div>
            </div>
        </div>
    </div>
</div>
</div>

But it still doesn't work, maybe I didn't quite understand the second part of your explanation?

chaudigv's avatar

@janmoes Have you added livewire styles and scripts?

<head>
    ...
    @livewireStyles
</head>
<body>
    ...
    @livewireScripts
</body>
</html>

Also verify that you have updated these assets by php artisan vendor:publish --force --tag=livewire:assets --ansi

Please check the Installation again to make sure you haven't missed something.

janmoes's avatar

I've added the style and script tags from livewire into the layouts/app.blade.php and executed the artisan command, but it still doesn't work :(

janmoes's avatar

Nope, that's why I usually use dd() to check if something even reaches the function.

prospero's avatar

And console return something after click? Check fist there

prospero's avatar

But in render $page_number is showns in view like 1 right?

prospero's avatar

I hope the others functions are working well and only this is the issue. Please test put buttons inside another div

<div>
   <span>{{ $page_number }}</span>
   <div>
       <button wire:click="decrement">-</button>
       <button wire:click="increment">+</button>
   </div>
</div>
janmoes's avatar

I haven't tested the other functions yet. I've started simple. If I can make those easy functions work, I'm sure I can figure the rest out too ;)

janmoes's avatar

If I remove everything except for only an empty div with those two buttons it works. But I need the entire html :'(

prospero's avatar

Here is something to check

@foreach($domains as $domain)
      <tr>
            <th scope="row">{{$domain->id}}</th> // td?
            <td>{{$domain->url}}</td>
janmoes's avatar
is also a but in font-weight; bold :)
1 like
prospero's avatar

If you have the @yield('content') directive you can do

return view('livewire.domain-list')
    ->extends('layouts.app')
    ->section('content');	
janmoes's avatar

I have the Yield directive in my app.blade.php and @section('content') in the blade file from my component, i've also added that ->section('content') but still nothing :(

prospero's avatar

Could you forget the two first div?

<div>
<div class="container">

I don't have any more ideas!

janmoes's avatar

Nope already had that in the first place :(

prospero's avatar

even doing this don't work?

 <div class="row justify-content-center">
        <div class="col-md-10">
            <div class="card">
                <div class="card-header">{{ __('Dashboard') }}</div>

                <div class="card-body">
                      buttons?
janmoes's avatar

Nope It still doesn't work. Since I have an empty div around all the other html I'm not sure what is going wrong

janmoes's avatar
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
    @livewireStyles
</head>
<body>
    <div id="app">
        <nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm">
            <div class="container">
                <a class="navbar-brand" href="{{ url('/') }}">
                    <svg width="100" height="50">
                    <img src="{{ asset('img/webprepare.svg') }}"><!--{{ config('app.name', 'Webprepare dashboard') }}-->
                    </svg>
                </a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
                    <span class="navbar-toggler-icon"></span>
                </button>

                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <!-- Left Side Of Navbar -->
                    <ul class="navbar-nav mr-auto">

                    </ul>

                    <!-- Right Side Of Navbar -->
                    <ul class="navbar-nav ml-auto">
                        <!-- Authentication Links -->
                        @guest
                            <li class="nav-item">
                                <a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
                            </li>
                            @if (Route::has('register'))
                                <li class="nav-item">
                                    <a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a>
                                </li>
                            @endif
                        @else
                            <li class="nav-item dropdown">
                                <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
                                    {{ Auth::user()->name }}
                                </a>

                                <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
                                    <a class="dropdown-item" href="{{ route('logout') }}"
                                       onclick="event.preventDefault();
                                                     document.getElementById('logout-form').submit();">
                                        {{ __('Logout') }}
                                    </a>

                                    <form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
                                        @csrf
                                    </form>
                                </div>
                            </li>
                        @endguest
                    </ul>
                </div>
            </div>
        </nav>

        <main class="py-4">
            @yield('content')
        </main>
    </div>
    @livewireScripts
</body>
</html>
``` Here you go :)
prospero's avatar

All well for me...dude, I can't explore in any more places, really don't know where is the issue. Please if you solve this, let us know then please. Sorry

janmoes's avatar

I appreciate your help! I remember earlier today that when I had like a plain component template that it worked. But since I've added everything it stopped working ;(

janmoes's avatar

I think I've come a little further. I know get the error Undefined index: links but when I dd() the code it works fine:

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use Illuminate\Support\Facades\Http;

class DomainList extends Component
{
    public $base_url = 'https://my.gridpane.com/oauth/api/v1/site?page=';
    public $page_number = 1;
    public $domains = [];
    public $first_page;
    public $last_page;
    public $prev = true;
    public $next = true;

    public function mount(){
        $response = Http::withOptions([ //use this method
            'verify'     => false, //This key and value in this method
        ])->withHeaders([
            'Content-Type'  => 'application/json',
            'Accept'        => 'application/json',
            'Authorization' => 'Bearer '.env('GRIDPANE_BEARER_TOKEN'),
            'data-raw'      =>  [
                'summary' => true,
            ],
        ])->get($this->base_url.$this->page_number);
        
        
        $this->first_page = $response['links']['first'];
        $this->last_page = $response['links']['last'];
        $this->domains = collect($response['data'])->map(fn($domain) => (object) $domain);
        // dd($this->domains);
    }

    public function increment(){
        $this->page_number++;
        // dd($this->page_number);
    }

    public function decrement(){
        $this->page_number--;
    }

    public function render()
    {
        return view('livewire.domain-list')
        ->extends('layouts.app');
    }
}

janmoes's avatar

I've got it kinda working now. The Domain list loads, and when I click on the increment/decrement button an error screen pops up with: ```Trying to get property 'id' of non-object (View: D:\wamp64\www\webprepare_dashboard\resources\views\livewire\domain-list.blade.php)` ``

//Component
class DomainList extends Component
{
    public $base_url = 'https://my.gridpane.com/oauth/api/v1/site?page=';
    public $page_number = 1;
    public $domains;
    public $first_page;
    public $last_page;
    public $prev = true;
    public $next = true;

    public function mount(){
        $response = Http::withOptions([ //use this method
            'verify'     => false, //This key and value in this method
        ])->withHeaders([
            'Content-Type'  => 'application/json',
            'Accept'        => 'application/json',
            'Authorization' => 'Bearer '.env('GRIDPANE_BEARER_TOKEN'),
            'data-raw'      =>  [
                'summary' => true,
            ],
        ])->get($this->base_url.$this->page_number);
        
        
        $this->first_page = $response['links']['first'];
        $this->last_page = $response['links']['last'];
        $this->domains = collect($response['data'])->map(fn($domain) => (object) $domain);
        // dd($this->domains);
    }

    public function increment(){
        $this->page_number++;
        // dd($this->page_number);
    }

    public function decrement(){
        $this->page_number--;
    }

    public function render()
    {
        return view('livewire.domain-list')->extends('layouts.app');
    }
}
//View from component
<div> 
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-10">
                <div class="card">
                    <div class="card-header">{{ __('Dashboard') }}</div>

                    <div class="card-body">
                        <h2 class="text-center">Domeinen</h2>
                        <div class="table-responsive">
                            <table class="table">
                                <thead>
                                    <tr>
                                        <th scope="col">ID</th>
                                        <th scope="col">Naam</th>
                                        <th scope="col">Opties</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    @foreach($domains as $domain)
                                    <tr>
                                        <th scope="row">{{$domain->id}}</th>
                                        <td>{{$domain->url}}</td>
                                        <td><a href="{{ route('domains.show', $domain->id) }}" class="btn btn-primary btn-font"><i class="fa fa-globe"></i> Bekijk domein details</a></td>
                                    </tr>
                                    @endforeach
                                </tbody>
                            </table>
                        </div>
                        <div>
                            <span>{{$page_number}}</span>
                            <button class="btn btn-success" wire:click="decrement">-</button>
                            <button class="btn btn-success" wire:click="increment">+</button>
                        </div>
                        <a href="{{ route('home') }}" class="btn btn-warning"><i class="fa fa-arrow-left"></i> Terug naar het dashboard</a>
                    </div>
                </div>
            </div>
        </div>
    </div>
    
</div>



Please or to participate in this conversation.