vue js axios response to array list - vue.js

i am working a typeahead. and my typeahead accept a array list like ['Canada', 'USA', 'Mexico'].
and now i have a axios api to get a list of country. but i don't know how can i convert to a array list. Now work if hardcode a country list.
<vue-bootstrap-typeahead
:data="addresses"
v-model="addressSearch"
/>
data() {
return {
addresses: ['Canada', 'USA', 'Mexico'],
addressSearch: '',
}
},
axios.get('api_link', {})
.then(function (response) {
//How can i create a array list from api return useing name like addresses?
})
And my api return:
[
{
"id": 1,
"name": "Canada"
},
{
"id": 2,
"name": "USA"
},
]

Make use of the created() lifecycle hook to get the data:
created() {
axios.get('api_link', {})
.then((response) => { this.addresses = response.data.map(x => x.name) })
}
In your data() make sure to initialize to an empty array:
data() {
return {
addresses: [],
...
}
Just so you see what the map function does:
console.log([ { "id": 1, "name": "Canada" }, { "id": 2, "name": "USA" }, ].map(x=>x.name))

You can use array.map to take only the names like this:
axios.get('api_link', {})
.then((response) => {
this.addresses = response.data.map(country => country.name)
})

Related

how to get list of product under categoryID in vuejs

I'm working on an app in which if a category is clicked it goes to another route and list the product under that category.
This is my html template category id routes :
<div>
<p>{{category.type}}</p>
<div
v-for="product in products(category._id)"
:key="product._id"
>
{{product.title}}
</div>
</div>
My script tag :
<script>
import axios from "axios";
export default {
name: "Product",
components: {},
data() {
return {
categoryID: null,
category: [],
products: [],
show: null
};
},
mounted() {
axios
.get(`http://localhost:5000/api/categories/${this.$route.params.id}`, {})
.then(response => {
console.log(response);
this.category = response.data.category;
})
.catch(error => {
console.log(error);
error;
});
axios
.get(`http://localhost:5000/api/products`, {})
.then(response => {
console.log(response);
this.product = response.data.product;
})
.catch(error => {
error;
});
},
};
</script>
Response I get in my console, the list of categories :
{
"success": true,
"category": {
"_id": "6220db08e861f3dbbaf21e39",
"products": [],
"type": "3 bedroom",
"__v": 0
}
}
This is my list of products :
{
"products": [
{
"_id": "6256711a0e42d6c5ab370e9d",
"category": {
"_id": "6220db08e861f3dbbaf21e39",
"products": [],
"type": "3 bedroom",
"__v": 0
},
"title": "galaxy s22",
"price": 200,
"stockQuantity": 1,
"__v": 0,
"id": "6256711a0e42d6c5ab370e9d"
},
]
}
my category api
router.get(`/categories/:id`, async (req, res) => {
try {
let category = await Category.findOne({
_id: req.params.id
})
res.json({
success: true,
category: category
});
} catch (err) {
res.status(500).json({
success: false,
message: err.message
});
}
});
How can I get the list of products under a specific category ? I get the {{ category.type }}
My suggestion is to filtered out the products in the script and then bind that in the template as you are getting only one category object from an API.
Demo :
new Vue({
el: '#app',
data: {
// This is a mock data just for a demo (actual will come from API)
category: {
"success": true,
"category": {
"_id": "6220db08e861f3dbbaf21e39",
"products": [],
"type": "3 bedroom",
"__v": 0
}
},
// This is a mock data just for a demo (actual will come from API)
products: [
{
"category": {
"_id": "6220db08e861f3dbbaf21e39"
},
"title": "galaxy s22"
}, {
"category": {
"_id": "6220db08e861f3dbbaf21e40"
},
"title": "galaxy s10"
}, {
"category": {
"_id": "6220db08e861f3dbbaf21e39"
},
"title": "galaxy s30"
}
]
},
mounted() {
this.products = this.products.filter(({ category }) => category._id === this.category.category._id);
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<p>{{category.category.type}}</p>
<ul>
<li v-for="product in products" :key="product._id">
{{ product.title }}
</li>
</ul>
</div>
To get the products for a category you can filter your products :
let categoryProducts = this.products.filter((p) => {
return p.category.type == this.category.type
})
But perhaps its better to only retrive products of that category from the server, without filtering on js, if you don't need the products of other categories
i don't know your api but something like that perhaps :
axios.get(`http://localhost:5000/api/products?category=` + this.category.id, {})
.then(response => {
console.log(response);
this.product = response.data.product;
})
.catch(error => {
error;
});
mounted() {
axios
.get(`http://localhost:5000/api/categories/${this.$route.params.id}`)
.then(response => {
this.category = response.data.category;
})
.catch(error => {
console.log(error);
});
}
By above api you will get category object which have products. so you don't need any other api. so now just loop using category.products.
<div
v-for="product in category.products"
:key="product._id"
>
{{product.title}}
</div>

TypeError: $data.quotation.company is undefined

I have problem when I try to render data in my Vue3 application.
data() {
return {
quotation: [],
}
},
mounted() {
this.getQuotation()
},
methods: {
async getQuotation() {
this.$store.commit('setIsLoading', true)
const quotationID = this.$route.params.id
await axios
.get(`/api/v1/quotations/${quotationID}/`)
.then((response) => {
this.quotation = response.data
})
.catch(error => {
console.log(error)
})
},
}
The weird part is when I try to access {{quotation.company}} in template I can see the element of "company" without any error. The error TypeError: $data.quotation.company is undefined occurs when I get in depth {{quotation.company.name}} for example.
Axios is getting data like:
{
"id": 20,
"company": {
"id": 4,
"name": "xxxx",
"slug": "xxx",
"categories": [
{
"id": 7,
"name": "xxxx",
"slug": "xxxx"
}
],
"street2": "",
"postcode": 11111,
},
"home_type": "xxxx",
"Urgency": "",
"description": "xxxx",
}
I really don't understand :/
First the quotation property should be declared as an object like quotation: {}, then at the first rendering the field company is not available yet, so you need to add some conditional rendering as follows :
<div v-if="quotation.company" >
{{quotation.company.name}
</div>

How to get the correct object in an nested array in Vue.js?

I use Axios to display a JSON data and I have succeeded. But I want to show an object based on date and time, it shows now all data and I need to filter it.
So I want to look at today's date and show the object based on that, so I want to show the next upcoming event. (24/05/2020)
What I currently have:
Json:
{
"doc": [
{
"data": {
"events": {
"18807612": {
"_dt": {
"_doc": "time",
"time": "18:45",
"date": "14/05/20",
"tz": "UTC",
"tzoffset": 0,
"uts": 1566067500
},
"week": 33,
"teams": {
"home": {
"name": "name 1",
"mediumname": "name1",
"uid": 3014
},
"away": {
"name": "name 2",
"mediumname": "name 2",
"uid": 3020
}
}
},
"18807618": {
"_dt": {
"_doc": "time",
"time": "18:45",
"date": "24/05/20",
"tz": "UTC",
"tzoffset": 0,
"uts": 1566067500
},
"week": 33,
"teams": {
"home": {
"name": "name 1",
"mediumname": "name1",
"uid": 3014
},
"away": {
"name": "name 2",
"mediumname": "name2",
"uid": 3020
}
}
}
}
}
}
]
}
Store:
async loadPosts({ commit }) {
// Define urls pages
const urlEvents = 'http://api.example.com/302020';
// Set pages
const [
responseEvents
] = await Promise.all([
// Responses pages
this.$axios.get(urlEvents)
]);
// variables pages
this.events = responseEvents.data.doc[0].data.events
// mutations pages
commit('SET_EVENTS', this.events)
}
},
mutations: {
SET_EVENTS (state, events) {
state.events = events;
}
}
And to show the data I use this:
import {mapState} from 'vuex';
export default {
name: 'NextMatch',
mounted() {
this.$store.dispatch('loadPosts')
},
computed: {
...mapState([
'events'
])
}
}
<h1>{{events}}</h1>
But this shows all data, and what I try to get is the first upcoming event for the object with the "uid": 3014.
So I want to show the date, time and names of the home and away team.
How can I get the correct data by filtering the data?
Something like this or similar to this should work:
In your Vue component's <template>:
`<h1>{{selectedEvent._dt.date}}</h1>`
In your Vue component's <script>:
props: {
eventID: {
type: Number,
default: 3014
},
},
computed: {
...mapState([
'events'
]),
eventsArr(){
if (!this.events) return {} //make sure Object.entries gets object.
return Object.entries(this.events)
},
selectedEvent(){
const selectedArr = this.eventsArr.find(([eID, e]) => e.teams.home.uid === this.eventID)
return selectedArr[1]
}
}

How to populate a v-select component with json data coming from axios.get

I am having a hard time trying to populate a v-select component with data from backend. The backend data is in json format.
The array 'items_category' is not storing the data. So I see "No data available" in my v-select. Can anyone help me. Thanks. This is my code:
<v-select v-model="category" :items="items_category" chips dense></v-select>
data () {
return {
category: '',
items_category: [],
categories: [],
i: 0
}
},
created () {
this.initialize()
},
methods: {
initialize () {
axios.get('http://localhost:4000/categories', {
})
.then(response => {
this.categories = response.data
for (this.i=0; this.i<this.categories.length; this.i++) {
this.items_category[this.i] = this.categories[this.i].category_name
}
})
.catch(function (error) {
console.log(error);
})
}
}
This is my json (http://localhost:4000/categories):
[
{
"id": 1,
"category_name": "Name 1",
"category_description": "Description 1"
},
{
"id": 2,
"category_name": "Premium",
"category_description": "Description 2"
},
{
"id": 3,
"category_name": "Free",
"category_description": "Description 3"
}
]
Ok I got it correct by using the push method
this.items_category.push(this.categories[this.i].category_name)

Shopping Cart with Vue and Vuex

I have cloned this awesome shopping cart repo from https://github.com/vueschool/learn-vuex, it works good but doesn't handle data for my use case. For anyone who has used this repo, how do i extend it by getting products from database or Api?
Shop.js
const _products = [
{"id": 1, "title": "iPad 4 Mini", "price": 500.01, "inventory": 2},
{"id": 2, "title": "H&M T-Shirt White", "price": 10.99,
"inventory": 10},
{"id": 3, "title": "Charli XCX - Sucker CD", "price": 19.99,
"inventory": 5}
]
export default {
getProducts (cb) {
setTimeout(() => cb(_products), 100)
},
buyProducts (products, cb, errorCb) {
setTimeout(() => {
// simulate random checkout failure.
(Math.random() > 0.5 ||
navigator.userAgent.indexOf('PhantomJS') > -1)
? cb()
: errorCb()
}, 100)
}
}
Shop gets called via vuex actions
actions: {
fetchProducts({commit}) {
return new Promise((resolve, reject) => {
// make the call
// call setProducts mutation
shop.getProducts(products => {
commit('setProducts', products)
resolve()
})
})
}
You can use axios to make a call to the server and get products like following
export default new Vuex.Store({
state: {
products: {},
},
actions: {
getProducts({commit},data) {
axios.get(`api/product?page=`+ data.page + '&orderBy='+ data.orderBy).then((response) => {
commit('updateProducts', response.data);
})
},
mutations: {
updateProducts (state, products) {
state.products = products
}
}
});