Reputation: 67
I'm fetching Data from an API using Axios and i'm displaying them as Cards in a Component called Books, the thing is that i want to be able to click on a single Book card and the router take me to another page with that book id from the API and displaying the Book specific data but the problem is that the vue-router is accepting the correct ID but i get the Data of another Book. For example: ( http://localhost:8080/books/1 ) will show the data of the second element of the array.
So how do i fix it?
this is my API:
{"error":false,"books":[{"id":"1","Title":"Harry Potter","Author":"J. K. Rowling","Price":"45"},{"id":"2","Title":"To Kill a Mockingbird","Author":"Harper Lee","Price":"40"},{"id":"3","Title":"Almukadimah","Author":"Ibn Khaldun","Price":"50"},{"id":"5","Title":"Into The Wild","Author":"Anonymous","Price":"15"}]}
Books.vue
<template>
<div class="container pt-5">
<div class="row">
<div class="col-md-4 col-6 mb-3" v-for="book in bookList" :key="book.id">
<router-link :to="{ name: 'book', params: { id : book.id-1 }}">
<div class="card">
<div class="card-header bg-primary text-text-capitalize d-flex flex-column justify-content-center align-items-center">
<h1 class="card-title text-center text-light">{{ book.Title }}</h1>
</div>
<div class="card-body">
<p>Irure laboris voluptate dolor officia mollit dolore aute qui tempor qui ut consectetur consequat pariatur laborum irure cupidatat minim officia non do do nulla dolore mollit nisi laboris qui officia sunt anim id veniam cupidatat et reprehenderit anim.</p>
</div>
<div class="card-footer">
<span class="font-weight-bolder">Author :<label class="font-font-weight-normal ml-2"> {{ book.Author }} </label></span>
</div>
</div>
</router-link>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Books",
data: function() {
return {
bookList: []
}
},
mounted: function() {
this.getBook();
},
methods: {
getBook() {
axios.get('http://localhost/VUEJS/src/Backend/api.php?action=read')
.then((res) => {
if (res.data.error) {
this.errorMsg = res.data.message;
} else {
this.bookList = res.data.books;
}
});
}
}
}
</script>
<style scoped>
.card{
transition: all 0.3s ease;
}
.card:hover{
box-shadow: 1px 0px 25px 0 rgba(189, 189, 185, 0.3);
transform: translateY(-4px);
}
.card-header {
height: 165px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
a{
color: #000;
text-decoration: none;
}
a:hover{
text-decoration: none;
}
</style>
Book.vue
<template>
<div class="text-center">
<h1 class="text-light text-center bg-dark py-3">{{ bookTitle }}</h1>
<p>LorAute est velit quis exercitation.Voluptate in nisi commodo aute.Nulla sint ut nostrud deserunt.
Ad et qui amet nulla culpa ex sunt culpa magna consequat quis fugiat aliqua dolore. Elit ex duis laborum veniam sunt do.
Aliqua mollit fugiat duis non qui elit nulla non occaecat ad reprehenderit.Anim irure nulla reprehenderit nulla officia reprehenderit voluptate excepteur.Culpa exercitation adipisicing cillum ipsum dolor.
Minim mollit dolor exercitation ex incididunt.Sit ad duis laborum dolore sit commodo voluptate laboris ullamco consequat.
</p>
<hr class="bg-info">
<span>{{ bookAuthor }}</span>
</div>
</template>
<script>
export default {
data: function() {
return {
id: this.$route.params.id,
bookTitle: '',
bookAuthor: ''
}
},
mounted: function() {
this.getBook();
},
methods: {
getBook() {
axios.get('http://localhost/VUEJS/src/Backend/api.php?action=read')
.then((res) => {
if (res.data.error) {
this.errorMsg = res.data.message;
} else {
this.bookTitle = res.data.books[this.id].Title;
this.bookAuthor = res.data.books[this.id].Author;
}
});
}
}
}
</script>
Upvotes: 0
Views: 1444
Reputation: 3452
If I understand you correctly then when you access http://localhost:8080/books/1 means you want to see the book with id: 1 (Harry Potter in the json example), which is element with index 0 in the array.
However in Book.vue you put this id into array index
this.bookTitle = res.data.books[this.id].Title; // it looks for res.data.books[1]
this.bookAuthor = res.data.books[this.id].Author;
So you need to change it to
this.bookTitle = res.data.books[this.id - 1].Title; // res.data.books[0]
this.bookAuthor = res.data.books[this.id - 1].Author;
However, this may have some error in the edge cases of the array. I suggest you can change it to filter function. For example:
this.bookTitle = res.data.books.filter(book => book.id === this.id)[0].Title;
Upvotes: 1