0

This is the 3rd attempt for me to get some help on this issue, for so long I've been trying to toggle an id using Vuejs, I just want that id to change based on a boolean value passed on from Laravel, I managed to do it without components but I ran into a problem, there's multiple buttons on the page, when one gets their id updated the others do as well, so I thought maybe a component could solve this, I just can't get it to work.

Here's the blade template, this is inside a table inside a foreach loop that has access to a $courses variable:

courses.blade:

<form method="POST" action="{{ route('course.completed', $course->name) }}" id="form-submit">
                       {{ csrf_field() }}
    @if ($course->pivot->completed == true)
    <course-buttons id="this.greenClass.aClass">Done</course-buttons>
    @else
    <course-buttons id="this.redClass.aClass">Not Yet</course-buttons>
    @endif
</form>

this is app.js:

require('./bootstrap');
Vue.component('course-buttons', require('./components/course-buttons.vue'))

var vm = new Vue({
el: '#app'
});

And this is the course-buttons.vue file:

<template>

  <button @click.prevent="onSubmit({{ $course }})" type="button" class="btn btn-sm" :id=id><slot></slot></button>

</template>

<script>
  export default {
    props: ['id'],
    data: function() {
      return {
        greenClass: {aClass: 'coursetrue', text: 'Done!'},
        redClass: {aClass: 'coursefalse', text: 'Not Yet!'}
      };
    },
    methods: {
      onSubmit: function(course) {
        axios.post('/MyCourses/' + course.name)
           .then(function (response){
             console.log(response.data.course.pivot.completed)

             if (response.data.course.pivot.completed == true){
               return [
                 vm.redClass.aClass = 'coursetrue',
                 vm.redClass.text = 'Done!',
                 vm.greenClass.aClass = 'coursetrue',
                 vm.greenClass.text = 'Done!'
               ]
             } else {
               return [
                 vm.greenClass.aClass = 'coursefalse',
                 vm.greenClass.text = 'Not Yet',
                 vm.redClass.aClass = 'coursefalse',
                 vm.redClass.text = 'Not Yet'
               ]
             }
           });
     }
    }
  }
</script>

First I know that my code isn't good, that's why I asked for help many times but with no answers at all, so if you have any tips that might help me get this code cleaner, even change it totally but just get the job done, I'm all ears.

The errors I'm getting right now is first the @click.prevent is an invalid expression, tried moving that to the tag, it doesn't do anything over there so I had that going before and now I lost it as well, also I get an error that the id is not defined on the instance, although I defined the props and data in the vue component. if you're wondering why do I even assign the id on the tag itself and not the component, it's because of how my code is structured,e.g "If the value is true then load the tag with that id, otherwise load it with that id", once again if you can help me do this in a completely different way I'll be grateful.

1 Answer 1

1

One error I see is you have to use v-bind:id here, as you are assigning a vue variable:

<course-buttons v-bind:id="this.greenClass.aClass">Done</course-buttons>

One more is in onSubmit method, you dont have to return anything, and also you are using vm there, instead of that you can just do following:

  onSubmit: function(course) {
    axios.post('/MyCourses/' + course.name)
       .then((response) => {
         console.log(response.data.course.pivot.completed)
         if (response.data.course.pivot.completed == true){
             this.redClass.aClass = 'coursetrue',
             this.redClass.text = 'Done!',
             this.greenClass.aClass = 'coursetrue',
             this.greenClass.text = 'Done!'
         } else {
             this.greenClass.aClass = 'coursefalse',
             this.greenClass.text = 'Not Yet',
             this.redClass.aClass = 'coursefalse',
             this.redClass.text = 'Not Yet'
         }
       });
 }

Here I have also used arrow syntax, here is why.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for the quick help, although I need some more, right now I did what you recommended and I'm getting "[Vue warn]: Error when rendering root instance" and "Uncaught TypeError: Cannot read property 'aClass' of undefined", do you think there's something wrong with how I declared the data on the component?
Also there is that issue of "[Vue warn]: failed to compile template: <button @click.prevent="onSubmit({{ $course }})" type="button" class="btn btn-sm" :id=id><slot></slot></button> - invalid expression: @click.prevent="onSubmit({{ $course }})" Which I have no idea how to correct.
@OmarTarek I noticed now, you are passing v-bind:id="this.greenClass.aClass", but this.greenClass is already data of your component, so either you move this data and loading of data to parent. see here how props works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.