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

kendrick's avatar

TypeError: null is not an object (evaluating 'task.task')

I am trying to loop through the created tasks only of the authenticated partner. Creation of tasks works.

With the setup below, i get the response TypeError: null is not an object (evaluating 'task.task') in my console. as I set task: null,

How can i get the task object and loop through the tasks and secure, that only the tasks of the authenticated partner will be shown (Task.php, 'partner_id')?


<template>

<div>
    <form @submit.prevent="save">
        <div class="row">
          <div class="col-md-9">
            <input name="task" placeholder="..."  v-model="task">
          </div>
          <div class="col-md-3">
          <button type="submit" class="button-none">
          <div >
              <h4><span>+</span></h4>
          </div>
          </button>  
          </div>
        </div>
    </form>

      <div v-for="task in tasks">
        <p>{{task.task}}</p>
      </div>
</div>


</template>

export default {

    props:['partner'],

    data(){
      return{
        tasks:[],  
        task: null, 
      }
    },

    methods:{
      save(){
        if(this.task){
          this.pushToTasks(this.task);
          axios.post(`/tasks`, {
            task: this.task, 
          })
       
        this.task = null;
        }
      },
 
      pushToTasks(task) {
        this.tasks.push({
          task: task,  
        });
      },
       
      getAllTasks(){
        axios
          .post(`/tasks`)
          .then(res => (this.tasks = res.data.data));

      }
    },

    created(){

      this.getAllTasks();

    },
 
  }
0 likes
54 replies
realrandyallen's avatar

Looks like you're passing in partner as a prop, so if you have the tasks for that partner on the partner object through an Eloquent relationship you could just use that in your Vue data:

export default {

    props:['partner'],

    data(){
      return{
        task: null, 
        tasks: this.partner.tasks,
      }
    },

    methods:{
      save(){
        if(this.task){
          this.pushToTasks(this.task);
          axios.post(`/tasks`, {
            task: this.task, 
          })
       
        this.task = null;
        }
      },
 
      pushToTasks(task) {
        this.tasks.push({
          task: task,  
        });
      },
 
  }
kendrick's avatar

Thank you @realrandyallen

Relationships are provided.

I guess the props are not passed. This will lead to:

TypeError: undefined is not an object (evaluating 'this.partner.tasks')
[Vue warn]: Computed property "tasks" was assigned to but it has no setter.

[Vue warn]: Property or method "task" is not defined on the instance but referenced during render.

[Vue warn]: Property or method "tasks" is not defined on the instance but referenced during render.
kendrick's avatar

@realrandyallen

<task-component :partner="{{Auth::user()}}"></task-component>

I now get:

TypeError: undefined is not an object (evaluating 'this.tasks.push')

when I try to push tasks to the db. A new record will be created but task remains null.

Why am I getting this error, if it worked before?

kendrick's avatar

Update:

data(){
      return{ 
        tasks: [],
        task: null
      }
    },

This way, I can push the tasks to db, and they will also be listed below the input, after pushing.

But when I reload the page, they don't persist in the view, but they are stored within db.

So I need a method to getAllTasks()

getAllTasks(){

        axios
          .post(`/tasks`)
          .then(res => (this.partner.tasks = res.data));

      },

How could I trigger this one?

kendrick's avatar

Thank you @realrandyallen


<template>

<div>
    <form @submit.prevent="save">
        <div class="row">
          <div class="col-md-9">
            <input name="task" placeholder="..."  v-model="task">
          </div>
          <div class="col-md-3">
          <button type="submit" class="button-none">
          <div >
              <h4><span>+</span></h4>
          </div>
          </button>  
          </div>
        </div>
    </form>

      <div v-for="task in tasks">
        <p>{{task.task}}</p>
      </div>
</div>


</template>

<script>
   


  export default {

    props:['partner'],

    data(){
      return{ 
        tasks: [],
        task: null
      }
    },

    methods:{



      save(){
        if(this.task){
          this.pushToTasks(this.task);
          axios.post(`/tasks`, {
            task: this.task, 
          })
       
        this.task = null;
        }
      },
 
      pushToTasks(task) {
        this.tasks.push({
          task: task,  
        });
      },

      
 
  },

 
}

</script>
realrandyallen's avatar

@SPLENDIDKEEN - I brought this code into my local environment and it's working just fine:

<template>

<div>
    <form @submit.prevent="save">
        <div class="row">
          <div class="col-md-9">
            <input name="task" placeholder="..."  v-model="task">
          </div>
          <div class="col-md-3">
          <button type="submit" class="button-none">
          <div >
              <h4><span>+</span></h4>
          </div>
          </button>  
          </div>
        </div>
    </form>

      <div v-for="task in tasks">
        <p>{{ task.task }}</p>
      </div>
</div>


</template>

<script>
    export default {
        props:['partner'],

        data() {
            return { 
                task: null,
                tasks: this.partner.tasks
            }
        },

        methods: {
            save(){
                const self = this;

                if (this.task) {
                    axios.post(`/tasks`, {
                        task: this.task, 
                    }).then((response) => {
                        self.pushToTasks(self.task);
                        self.task = null;
                    }).error((response) => {
                        console.log(response);
                    });
                }
            },

            pushToTasks(task) {
                this.tasks.push({
                    task: task,  
                });
            }
        },
    }
</script>
kendrick's avatar

It works, but only shows the Tasks after pushing them to the db, if I refresh the page, they are gone. @realrandyallen

So the loop through the tasks is not working. How can I get all tasks?

These are my relations:

Partner.php

public function tasks()
{
 return $this->hasMany(Task::class);
}

Task.php

public function partner()
{
return $this->belongsTo(Partner::class, 'partner_id');
}
realrandyallen's avatar

@SPLENDIDKEEN - Your relationships look fine...are the new tasks being successfully persisted to the DB? If so maybe you just need to grab a fresh instance of the partner so the new tasks are on the object:

<tasks :partner="{{ auth()->user()->fresh() }}"></tasks>
kendrick's avatar

Thank you for coming back @realrandyallen

Yes, the new tasks persist in the DB.

<tasks :partner="{{ auth()->user()->fresh() }}"></tasks>

represents a new Component?

realrandyallen's avatar

@SPLENDIDKEEN - Nope, sorry I just assumed your component name - looking at your code above it'd be:

<task-component :partner="{{ auth()->user()->fresh() }}"></task-component>
kendrick's avatar

It just won't work. @realrandyallen

I have to add (both ways the task is pushed to db), but

if I use

data() {
                return { 
                    task: null,
                    tasks: []
                }
            },

the task will be added to the ul

If I use

data() {
            return { 
                task: null,
                tasks: this.partner.tasks
            }
        },

I get

Unhandled Promise Rejection: TypeError: undefined is not an object (evaluating 'this.tasks.push')

Task will be pushed to db, but error occurs and the task remains in the input.

What is a simple way to iterate over all tasks in the tasks table?

realrandyallen's avatar

@SPLENDIDKEEN - Looks like iterating over the tasks is working fine, it's just pushing the new task to the this.tasks object is failing because Vue apparently can't see it

Do you have the Vue devtools installed for Chrome so you can see the tasks data? It should look something like this:

https://imgur.com/a/TjFugDS

kendrick's avatar

Yes, yours make sense. @realrandyallen

I get the same structure, after pushing a task (data: tasks:[]), but again it just won't remain in the view. Still facing the same problem.

return { 
task: null,
tasks: this.partner.tasks
}

app.js:58856 Uncaught (in promise) TypeError: Cannot read property 'push' of undefined
    at VueComponent.pushToTasks
realrandyallen's avatar

@SPLENDIDKEEN - Post all the code of the component one more time and I'll take another look - if I don't see anything wrong maybe we need a pair of fresh eyes

kendrick's avatar

Thank you for your patience @realrandyallen

TaskComponent.vue

<template>
<div>
    <form @submit.prevent="save">
        <div class="row">
          <div class="col-md-9">
            <input name="task" placeholder="Type task here..." v-model="task">
          </div>
          <div class="col-md-3">
          <button type="submit">
          <div>
              <h4><span>+</span></h4>
          </div>
          </button>  
          </div>
        </div>
    </form>
    
    // Should list all tasks of the Partner, and add every newly pushed task below  

    <div v-for="task in tasks">
            <p>{{task.task}}</p>
        </div>
      
</div>


</template>


<script>
   
export default {
    props:['partner'], // Object is given (Vue Devtools)

    data() {
        return {  
            task: null,
            tasks: [],
        }
    },

    methods: {
        save(){
            const self = this;

            if (this.task) {
                axios.post(`/tasks`, {
                    task: this.task, 
                }).then((response) => {
                    self.pushToTasks(self.task);
                    self.task = null;
                });
            }
        },

        pushToTasks(task) {
            this.tasks.push({
                task: task,  
            });
        }
    },
}

</script>

home.blade.php

<tasks-component :partner="{{Auth::user()}}"></tasks-component> // Authenticated Partner

Basically, I believe something like getAllTasks() is missing?

realrandyallen's avatar

@SPLENDIDKEEN - No worries....I still don't think you need a getAllTasks() as this should work fine:

    data() {
        return {  
            task: null,
            tasks: this.partner.tasks,
        }
    },

I'm not sure why the pushToTasks method is saying this.tasks is undefined...I'm doing this locally on my machine and it's working fine.

You're doing a npm run dev after you've made these changes? Or you have npm run watch on?

kendrick's avatar

npm run watch @realrandyallen

npm run dev both way tasks: [] / tasks: this.partner.tasks, results in the same behavior.

tasks:[], returns an array of null, but lists the tasks after pushing them, after refresh tasks are gone

tasks: this.partner.tasks, returns the push error, and is just undefined (Vue devtools)

Both ways, tasks are pushed to DB.

realrandyallen's avatar

@SPLENDIDKEEN - Outside of pushing your entire codebase up to github so I can clone an exact copy of what you have I'm not sure I can point you in the right direction...sorry I couldn't help you further

kendrick's avatar

Thank you @realrandyallen

Is there a way to get behind it by console.logging maybe a relation or something equal? Maybe then I will find a way through it.

1 like
kendrick's avatar

Gives me the expected collection. @realrandyallen

I could create a foreach loop, but this would not dynamically show the new tasks, only after refresh, which wouldn't make any sense, then, using vue.

This is my TaskController, task() method:

public function task(Request $request){

        $partner = Auth::user();
        $task = $partner->tasks()->create([
              'task' => $request->task,
              'partner_id' => $partner->id,
        ]);
        return response($task, 200);
}
realrandyallen's avatar

@SPLENDIDKEEN - After another cup of coffee it hit me that if a partner doesn't have any tasks that's probably creating an issue...try this:

        data() {
            return { 
                task: null,
                tasks: this.partner.tasks ? this.partner.tasks : []
            }
        },

I also typo'd the axios code:

                    axios.post('/tasks', {
                        task: this.task, 
                    }).then((response) => {
                        self.pushToTasks(self.task);
                        self.task = null;
                    }).catch((response) => {
                        console.log(response);
                    });
kendrick's avatar

Pushing to the db works without a error, the tasks will be listed below, but again after a refresh tasks equals Array[0]. It just can't grab the tasks. This is so frustrating, as it seams so simple.

Again, thank you for your patience. @realrandyallen

realrandyallen's avatar

@SPLENDIDKEEN - Well at least we've made progress :) It also just hit me that you're using a model called Partner and not the default User model I assumed so that means doing this:

<tasks :partner="{{ auth()->user() }}"></tasks>

Is not going to work since the authenticated user is an instance of User, not Partner.

You'll need to grab the correct partner in your controller and pass it to the component:

<tasks :partner="{{ $partner }}"></tasks>

Alternatively, if you are using Partner for your users rather than User you can change that in your config/auth.php file

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Partner::class,
        ],

At that point auth()->user() should work if you wanted to do it that way

1 like
kendrick's avatar

Yes, also thought about it, I used {{Auth::user()}}, I guess that worked, but I changed it to $partner, but still remains the same behavior. @realrandyallen

What strikes me is, if I e.g. add:

data() {
   return { 
        task: null,
        tasks: this.partner.tasks ? this.partner.tasks : [],
ptest: this.partner.name, // it returns the name, so the partner is provided.
    }
},

Somehow it just can't get the tasks relation, even though it is provided.

Next

Please or to participate in this conversation.