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

realrandyallen's avatar

@SPLENDIDKEEN - Are you sure the partner_id's in your task table are being set right?

public function task(Request $request){

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

You're setting $partner here to Auth::user(), if you don't have the Partner model using the users table or haven't setup config/auth.php properly I could see that being an issue

kendrick's avatar

partner_id is set correct. Auth.php is also set correctly, Partner.php has its own provider, as well as guard. @realrandyallen

realrandyallen's avatar
Level 44

@splendidkeen - Are you eager loading the tasks with $with?

Partner model

use Illuminate\Database\Eloquent\Model;

class Partner extends Model
{
   ...

   protected $with = ['tasks'];

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

   ...
}
1 like
kendrick's avatar

What a journey @realrandyallen

Thank you for your great patience. Really appreciate it.

So basically, when working with components, always eager loading?

1 like
realrandyallen's avatar

@SPLENDIDKEEN - haha I'm glad we got there my friend, I'm sorry it took me so long to put the pieces together.

As for eager loading, as Jeffrey would say 'it depends'...sometimes it's a great idea, other times you do too much of it and it can cause performance issues.

The alternative here if you didn't eager load it from the model would be loading it manually in your controller like:

$partner = auth()->user()->loadMissing('tasks');

Either way would work...if you find yourself needing a partner's tasks in multiple places in your app then I would just leave it on the model.

1 like
kendrick's avatar

Please don't apologize. Couldn't work it out without your great help. @realrandyallen

I will stay with the eager loading for now, also try it in the controller.

Do you have good references in mind, to manipulate or sort the object, by e.g created_at, within the component?

1 like
kendrick's avatar

Great, thanks. @realrandyallen

computed: {
      orderedTasks: function () {
        return _.orderBy(this.partner.tasks, 'created_at', 'desc')
      }
    },
task in orderedTasks
1 like
kendrick's avatar

Not yet @realrandyallen , if I push the new Task it will not be listed within the ````task in orderedTasks```. Need to refresh, then it will be sorted in. I guess because its computed?

computed: {
      orderedTasks: function () {
        return _.orderBy(this.partner.tasks ? this.partner.tasks : [], 'created_at', 'desc')
      }
    },
realrandyallen's avatar

@SPLENDIDKEEN - Instead of ordering by this.partner.tasks order by this.tasks instead. Remember that the tasks on the partner aren't actually changing in the component, you're pushing to this.tasks in the component

return _.orderBy(this.tasks ? this.tasks : [], 'created_at', 'desc')
1 like
kendrick's avatar

You are right. Great @realrandyallen

Now I just need to add a delete function, and the fundament would be created. Therefore I would add a delete method, within the v-for loop, so I can get the task, that I want to delete.

And then add a delete() method, which basically posts a delete method from the Controller, correct?

TaskController

public function destroy($id){
       $task = Auth::user()->tasks()->findOrFail($id); 
       $task->delete();
        return response($task, 200);
    }

and pass the task.id to the post route.


delete(){
if (this.task) {
axios.post('/task/${this.task.id}'/delete', {
  this.delete  
});
}
}

Does this make sense, before testing?

realrandyallen's avatar

@SPLENDIDKEEN - Can't test this at the moment but I'd do something like this

task-component

<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 orderedTasks">
        <p>
          <span>{{ task.task }}</span>
          <button @click="deleteTask(task.id)">Delete</button>
        </p>
      </div>
</div>


</template>

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

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

        computed: {
          orderedTasks: function () {
            return _.orderBy(this.tasks ? this.tasks : [], 'task')
          }
        },

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

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

            deleteTask(taskId) {
              const self = this;

              axios.delete('/tasks/' + taskId)
                .then((response) => {
                    self.removeTask(taskId);
                }).catch((response) => {
                    console.log(response);
                });
            },

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

            removeTask(taskId) {
              this.tasks = _.remove(this.tasks, (task) => { return task.id != taskId });  
            }
        },
    }
</script>

routes/web.php

Route::delete('/tasks/{$task}', 'TaskController@destroy');

TaskController

public function destroy(Task $task) {
   $task->delete();

   return response($task, 200);
}

Note this line self.pushToTasks(response.data.task);

You can no longer just push this.task because we now need the ID of the new task from the DB so we can delete it if need be.

1 like
kendrick's avatar

Again thank you for your great help and ideas. @realrandyallen

Pushing works fine with self.pushToTasks(response.data.task);

removeTask(taskId) returns a 404 not found http://127.0.0.1:8000/tasks/112 404 (Not Found)

And I recognized, that if we push a new Task, and then directly want to remove it: http://127.0.0.1:8000/tasks/undefined 404 (Not Found) -> the id is undefined.

Tasks are not getting deleted, from the DB and within the loop, yet.

realrandyallen's avatar

@SPLENDIDKEEN - For the 404 make sure you setup that delete route properly in routes/web.php

When you try to delete a new task it looks like the id is undefined. When you store the new task in php you have to return the task with its new id from the db or your new delete function won’t work for new tasks.

kendrick's avatar

Web.php is set properly @realrandyallen

Route::delete('/tasks/{$task}', 'TaskController@destroy')->middleware('auth:partner');

This is the exact response

DELETE http://127.0.0.1:8000/tasks/1 404 (Not Found)

Error: Request failed with status code 404
    at createError (app.js:24940)
    at settle (app.js:47079)
    at XMLHttpRequest.handleLoad (app.js:24814)

XHR failed loading: DELETE "http://127.0.0.1:8000/tasks/1".

Tried to return the task with id, this way (still undefined)

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

Then, I might pass the {$task} to the post route?

realrandyallen's avatar

@SPLENDIDKEEN - Oops, remove that $

Route::delete('/tasks/{task}', 'TaskController@destroy')->middleware('auth:partner');

You also can leave this.tasks.push the way it was before. The issue should be in your TaskController when you store the new task - you may not be returning the task properly with its id...post the code if you wish

1 like
kendrick's avatar

Super. Thank you, delete works fine, for already created tasks. @realrandyallen

This is the post 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 - Use something like this

TaskController@store

...

if ($request->wantsJson()) {
   return response()->json(['message' => 'Task Saved', 'task' => $task], 200);
}

return response($task, 200);

Then in your component in the save method:

self.pushToTasks(response.data.task);

Should work, if not do a console.log(response) and check the console to make sure the task is returning properly with it's ID

1 like
kendrick's avatar

Again thank you @realrandyallen

Component is set properly.

After pushing the task, it outputs

{ "task": "Hey", "partner_id": 28, "updated_at": "2018-11-22 13:19:57", "created_at": "2018-11-22 13:19:57", "id": 6 } // Id is provided

Still undefined, when deleting the task above. After refresh it works, both the output (only task), and the axios delete method.

kendrick's avatar

task = store @realrandyallen

public function task(Request $request){

        $partner = Auth::user();

        $task = $partner->tasks()->create([ 
              'task' => $request->task,
              'partner_id' => $partner->id,
        
        ]);

        if ($request->wantsJson()) {
           return response()->json(['message' => 'Task Saved', 'task' => $task], 200);
        }

        return response($task, 200);

    }

Component


 <button @click="deleteTask(task.id)" class="button-none"><div class="icon"></div></button>

_____

props:['partner'],

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

    computed: {
      orderedTasks: function () {
        return _.orderBy(this.tasks ? this.tasks : [], 'created_at', 'desc')
      }
    },


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

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

        deleteTask(taskId) {
              const self = this;

              axios.delete('/tasks/' + taskId)
                .then((response) => {
                    self.removeTask(taskId);
                }).catch((response) => {
                    console.log(response);
                });
        },

        pushToTasks(task) {
            this.tasks.push({
                task: task,  
                created_at: "Just Now", 
            });
        },

        removeTask(taskId) {
              this.tasks = _.remove(this.tasks, (task) => { return task.id != taskId });  
        }
    },

Previous

Please or to participate in this conversation.