0

I have a Vue component that load the data of books from the back-end and then put then into cards.

I wanted to allow the user to change the sorting of the books from default to by rating or the newest etc, so I declared a variable name sorting and set to default and add a drop-drown menu to change the variable sorting from default, and put the variable in the URL that get the data from the back end like in get_books method:

data(){
    return {
        audio_books:[],
        page:1,
        last_page:false,
        sorting:"default",
    }

},
methods: {
    get_books() {
        axios.get('load_all_audio_books/'+this.sorting+'?page='+this.page).then(response=> {
            $.each(response.data.data, (key, v) => {
                this.audio_books.push(v);
                if (response.data.current_page==response.data.last_page){
                    this.last_page=true;
                }

            });
        })
        this.page++;

    },

the back end :- web.php

Route::get('/load_all_audio_books/{sort}',[\App\Http\Controllers\load_book::class,'get_all_audiobooks']);

the back-end function:-

public function get_all_audiobooks($sort)
{
    if($sort=="default")
    {
        $books=DB::table('audio_books')->paginate(10);
        return $books;
    }
    elseif ($sort=="rate")
    {
        $books=DB::table('audio_books')->orderBy('rating','desc')->paginate(10);
        return $books;
    }
    elseif ($sort=="newest")
    {
        $books=DB::table('audio_books')->orderBy('created_at','desc')->paginate(10);
        return $books;
    }
    elseif ($sort=="oldest")
    {
        $books=DB::table('audio_books')->orderBy('rating')->paginate(10);
        return $books;
    }

now what I want is to re-render the component whenever the variable sorting change.

2 Answers 2

3

If you want to perform the sorting in the backend, you are half way there (I found the page part confusing so I temporarily removed it from my demo below).

  1. Create a method that fires the HTTP call (Done per method get_books)
  2. Create a watcher that listens for changes in the value of sorting.
  3. Use the watcher to fire off the HTTP call again
<template>
<!-- Other stuff -->
<select v-model="sorting">
  <option value="prop1">Prop 1</option>
  <option value="prop2">Prop 2</option>
</select>
<!-- Other stuff -->
</template>

<script>
watch: {
  sorting(newVal, oldVal) {
    this.get_books(newVal)
  }
},
mounted() {
  this.get_books(this.sorting)
},
methods: {
  get_books(sort) {
        axios.get(`load_all_audio_books/${sort`).then(response=> {
            $.each(response.data.data, (key, v) => {
                this.audio_books.push(v);
                if (response.data.current_page==response.data.last_page){
                    this.last_page=true;
                }

            });
        })
    },
}
</script>

Watchers are one solution. You could do this in a multiple different ways.

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

Comments

0

I solved it by adding these two line to the function that changes the value of the variable "sorting"

change_sort(sort)
    {
        this.page=1;
        this.sorting=sort;
        //the first line empty the audio_books array
        this.audio_books=[];
        //the second line call the function that get the data from the 
        //back end with the new sorting value then repopulate the 
       //audio_books array with the new values 
        this.get_books();
       

    }

1 Comment

Although your solution is correct, it isn't efficient. You are adding another method that you don't need to. Having said that, if it makes sense to you, then I would use it :)

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.