Why is the section of my view disappears on render?

I have a view made with livewire and it contains two dynamically add sections for spoken languages and the other one for courses and certificates. The language section was working fine until I added the add certificates section. now when the user clicks on the add section for the certificate section to add a new one, one of the added language sections disappears and then will appear again once you add another one. I guess it will appear again once the view re-renders. I have been going back and force moving functions around from render method to update/updated/hydrate/dehydrate but got no luck. at first, I thought it had something to do with the $loop->index that I use in my view but after changing that I realized it was not it. I’m hitting a dead-end here and can’t figure out what’s going on here.

I also made a screen record of what is happening so it might help: https://drive.google.com/file/d/1Hq2wTKcPvhs05SKFMICaRoOAzpSyj9Iz/view?usp=sharing

View section:

<!-- language section -->
<div class="card card-profile shadow-sm mt-4">
    <div class="px-4 mt-4 mb-4">
        <div class="h5 font-weight-bold mb-4">Spoken languages</div>
        <div class="heading text-muted mb-4">you only can add 3 languages to your profile.</div>
            @foreach ($languages as $lindex => $language)
                <div class="card card-body mb-4" wire:key="{{ $lindex }}">
                    <div class="text-left"><span class="fa fa-trash text-gray language-delete" wire:click="removeLanguage({{ $lindex }}, {{ !empty($language['id']) ? $language['id'] : 0 }})"></span></div>
                    <div class="row">
                        <div class="form-group col-md-6">
                            <label class="" for="languageName">language</label>
                            <select class="form-control form-control-alternative" name="language-name" {{-- id="languageName" --}} wire:model="languages.{{ $lindex }}.language_name">
                                <option value="" class="form-control" selected disabled>select language</option>
                                @foreach ($language_names as $name)
                                    <option value="{{ $name->abbreviation }}" class="form-control">{{ $name->language }}</option>
                                @endforeach
                            </select>
                        </div>
                        <div class="form-group col-md-6">
                            <label class="" for="languageProficiency">proficiency level</label>
                            <select class="form-control form-control-alternative" name="language-proficiency" {{-- id="languageProficiency" --}} wire:model="languages.{{ $lindex }}.language_level">
                                <option value="" class="form-control" selected disabled>proficiency level</option>
                                @foreach ($language_levels as $level)
                                    <option value="{{ $level->level }}" class="form-control">{{ $level->name }}</option>
                                @endforeach
                            </select>
                        </div>
                    </div>
                </div>
            @endforeach

            @error('languages.*.language_level')
                <small class="text-warning">{{ $message }}</small>
            @enderror
            @error('languages.*.language_language')
                <small class="text-warning">{{ $message }}</small>
            @enderror

            @if (count($languages) < 3)
                <div class="row">
                    <div class="col-md-12">
                        <button type="button" class="btn btn-outline-secondary btn-round btn-block" wire:click="addLanguage"><span class="btn-inner--icon"><i class="fa fa-plus fa-2x"></i></span></button>
                    </div>
                </div>
            @endif

    </div>
</div>
<!-- end language section -->

<!-- other certificates section -->
<div class="card card-profile shadow-sm mt-4">
    <div class="px-4 mt-4 mb-4">
        <div class="h5 font-weight-bold mb-4">Other related certificates</div>
        <div class="heading text-muted mb-4">if you have other related certificates in your files you can add then here.</div>
        @foreach ($certificates as $cindex => $certificate)
            <div class="card card-body mb-4" wire:key="{{ $cindex }}">
                <div class="row">
                    <div class="form-group col-md-6">
                        <label class="" for="other-certificates-name">certificate name</label>
                        <input type="text" class="form-control form-control-alternative" placeholder="" name="ptherCertificatesName">
                    </div>
                    <div class="form-group col-md-6">
                        <label class="" for="other-certificates-school-name">School name</label>
                        <input type="text" class="form-control form-control-alternative" placeholder="" name="otherCertificatesSchoolName">
                    </div>
                    <div class="form-group col-md-6">
                        <label class="" for="other-certificates-verification-link">URL<small>(optional)</small></label>
                        <input type="text" class="form-control form-control-alternative text-left" placeholder="" name="otherCertificatesVerificationLink">
                    </div>
                    <div class="form-group col" dir="ltr">
                        <label class="" for="other-certificates-grad-date" dir="rtl">finished date</label>
                        <div class="input-group input-group-alternative">
                            <div class="input-group-prepend">
                            <span class="input-group-text"><i class="ni ni-calendar-grid-58"></i></span>
                            </div>
                            <input type="text" class="form-control form-control-alternative datePicker" placeholder="" name="otherCertificatesGradDate" value="">
                        </div>
                    </div>
                </div>
            </div>
        @endforeach
        @if (count($certificates) < 5)
            <div class="row">
                <div class="col-md-12">
                <button type="button" class="btn btn-outline-secondary btn-round btn-block" wire:click="addCertificate"><span class="btn-inner--icon"><i class="fa fa-plus fa-2x"></i></span></button>
                </div>
            </div>
        @endif
    </div>
</div>
<!-- end other certificates section -->

Livewire component controller:

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use App\Models\CityName;
use App\Models\Language;
use App\Models\LanguageLevel;
use App\Models\User;
use App\Models\UserLanguage;
use App\Models\UserProfile;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Auth;

class UserInfo extends Component
{
    public $name;
    public $email;
    public $phone;
    public $states = [];
    public $selectedstate;
    public $cities = [];
    public $selectedcity;
    public $jobTitle;
    public $aboutMe;

    public $employer;
    public $position;

    public $edu_course;
    public $edu_school;
    public $edu_level;
    public $edu_start_date;
    public $edu_end_date;

    public $employment_looking;
    public $employment_hired;

    public $twitter;
    public $linkedin;
    public $github;
    public $instagram;
    public $website;

    public $languages = [];
    public $language_names;
    public $language_levels;
    public $languageToDelete = [];

    public $certificates = [];
    public $certificate_name;
    public $certificate_school;
    public $certificate_link;
    public $certificate_date;
    public $certificateToDelete = [];

    public $skillsQuery;
    public $skillResults;

    public $skills;





    public function render()
    {
        $this->retriveStates();
        $this->retriveCities();
        $this->retriveLanguages();
        return view('livewire.user-info');
    }



    public function retriveStates()
    {
        $this->states = CityName::distinct()->get(['state']);
    }


    public function retriveCities()
    {
        $this->cities = CityName::where('state', $this->selectedstate)->get(['city']);
    }


    public function updatedSkillsQuery()
    {
        $this->skillResults = $this->skills->where('name', 'like', $this->skillsQuery) ?? collect();
    }


    public function retriveLanguages()
    {
        $this->language_names = Language::all();
        $this->language_levels = LanguageLevel::all();
    }


    public function addLanguage()
    {
        if (count($this->languages) <= 3)
        {
            array_push($this->languages, ['language_name'=>'', 'language_level'=>'', 'id'=>'']);
        }
        else
        {
            $this->sweetAlert('error', 'you only can add 3 languages to your profile.');
        }
    }


    public function getUserLanguages()
    {
        $this->languages = auth()->user()->userLanguages->toArray();
    }


    public function removeLanguage($languagePosition, $languageId)
    {
        if (isset($languageId))
        {
            if ($languageId == 0)
            {
                array_splice($this->languages, $languagePosition, 1);
            }
            else
            {
                array_push($this->languageToDelete, $languageId);
                array_splice($this->languages, $languagePosition, 1);
            }
        }
    }


    public function addCertificate()
    {
        if (count($this->certificates) <= 5)
        {
            array_push($this->certificates, ['name'=>'', 'school'=>'', 'link'=>'', 'date'=>'', 'id'=>'']);
            /* dd($this->languages); */
        }
        else
        {
            $this->sweetAlert('error', 'you only can add 5 certificates to your profile.');
        }
    }


    public function mount()
    {

        $this->skills = collect([
            ['name' => 'vue'],
            ['name' => 'vue'],
            ['name' => 'vue'],
            ['name' => 'laravel'],
            ['name' => 'laravel'],
            ['name' => 'laravel'],
        ]);

        $this->skillResults= [];
        $this->skillsQuery = '';
        /* $this->retriveLanguages();
        $this->retriveStates();
        $this->retriveCities(); */
        $this->getUserLanguages();
        $this->name = auth()->user()->name;
        $this->email = auth()->user()->email;
        $this->phone = auth()->user()->phone;
        $this->selectedstate = auth()->user()->userprofile->state;
        $this->selectedcity = auth()->user()->userprofile->city;
        $this->jobTitle = auth()->user()->userprofile->job_title;
        $this->aboutMe = auth()->user()->userprofile->about_me;
        $this->employer = auth()->user()->userprofile->employer;
        $this->position = auth()->user()->userprofile->position;
        $this->edu_course = auth()->user()->userprofile->edu_course;
        $this->edu_school = auth()->user()->userprofile->edu_school;
        $this->edu_level = auth()->user()->userprofile->edu_level;
        $this->edu_start_date = auth()->user()->userprofile->edu_start_date;
        $this->edu_end_date = auth()->user()->userprofile->edu_end_date;
        $this->employment_looking = auth()->user()->userprofile->employment_looking;
        $this->employment_hired = auth()->user()->userprofile->employment_hired;
        $this->twitter = auth()->user()->userprofile->twitter;
        $this->linkedin = auth()->user()->userprofile->linkedin;
        $this->github = auth()->user()->userprofile->github;
        $this->instagram = auth()->user()->userprofile->instagram;
        $this->website = auth()->user()->userprofile->website;

    }


    public function rules()
    {
        return [
            'name' => ['required', 'string', 'max:250'],
            'email' => [
                'required',
                'email',
                'max:250',
                Rule::unique('users')->ignore(auth()->id()),
            ],
            'phone' => ['required', 'digits:11'],
            'selectedstate' => 'required',
            'selectedcity' => 'required',
            'jobTitle' => ['required', 'string', 'max:250'],
            'aboutMe' => ['required', 'string', 'max:250'],
            'employer' => ['string', 'max:250'],
            'position' => ['string', 'max:250'],
            'edu_course' => ['nullable', 'string', 'max:250'],
            'edu_school' => ['nullable', 'string', 'max:250'],
            'edu_level' => ['nullable', 'string', 'max:250'],
            'edu_start_date' => ['nullable', 'string'],
            'edu_end_date' => ['nullable', 'string'],
            'employment_looking' => ['nullable', 'boolean'],
            'employment_hired' => ['nullable', 'boolean'],
            'twitter' => ['nullable', 'string', 'max:250'],
            'linkedin' => ['nullable', 'string', 'max:250'],
            'github' => ['nullable', 'string', 'max:250'],
            'instagram' => ['nullable', 'string', 'max:250'],
            'website' => ['nullable', 'string', 'max:250'],
            'languages.*.language_name' => ['required', 'exists:App\Models\Language,abbreviation'],
            'languages.*.language_level' => ['required', 'exists:App\Models\LanguageLevel,level'],
        ];
    }


    public function submit()
    {
        $user = Auth::user();

        $this->validate();

        User::where('id', auth()->id())->update([
            'name' => $this->name,
            'email' => $this->email,
            'phone' => $this->phone,
        ]);

        UserProfile::where('user_id', auth()->id())->update([
            'state' => $this->selectedstate,
            'city' => $this->selectedcity,
            'job_title' => $this->jobTitle,
            'about_me' => $this->aboutMe,
            'employer' => $this->employer,
            'position' => $this->position,
            'edu_course' => $this->edu_course,
            'edu_school' => $this->edu_school,
            'edu_level' => $this->edu_level,
            'edu_start_date' => $this->edu_start_date,
            'edu_end_date' => $this->edu_end_date,
            'employment_looking' => $this->employment_looking,
            'employment_hired' => $this->employment_hired,
            'twitter' => $this->twitter,
            'linkedin' => $this->linkedin,
            'github' => $this->github,
            'instagram' => $this->instagram,
            'website' => $this->website,
        ]);


        if (!empty($this->languageToDelete))
        {
            /* $user = Auth::user(); */
            foreach ($this->languageToDelete as $delete)
            {
                $user->userLanguages()->where('id', $delete)->delete();
            }
        }

        foreach ($this->languages as $language)
        {
            /* $user = Auth::user(); */
            $user->userLanguages()->updateOrCreate([
                'language_name' => $language['language_name'],
            ],
            [
                'language_name' => $language['language_name'],
                'language_level' => $language['language_level']
            ]
            );

        }

        $this->getUserLanguages();

        $this->sweetAlert('success', 'changes saved!');

    }


    public function sweetAlert($type, $message)
    {
        $this->alert($type, $message, [
            'position'  =>  'bottom-end',
            'timer'  =>  5000,
            'toast'  =>  true,
            'text' => null,
            'showCancelButton'  =>  false,
            'showConfirmButton'  =>  false
        ]);
    }

}

you MUST have a single root element in your livewire view. Do you?

I do. everything is in a single root div element.

clearly a dom diffing issue, Make sure your sections have id’s or distinct wire:key

At first, i thought maybe the wire:key="{{$loop->index}}" is causing the issue then I changed it as you see in the code to something distinct which are $cindex for the certificate section and $lindex for the language section but still the same issue. It’s days I’m hitting my head to the wall for this issue but could not find any answer nor anyone had any answer for it.

Just using the id is not a good idea as both sections could have the same ids and will definitely have the same loop index. You can prefix the key to make it unique

eg

wire:key="lang{{$loop->index}}"

OMG. that fixed the issue. you are a savior. Thanks a lot.