find data array in computed vuejs - vue.js

i have data
<div class="marginleft">{{locations}}</div>
and this my computed
computed : {
...mapState({ result_estimate: (state) => state.res_estimate }),
...mapState({ prov: (state) => state.provinsi }),
locations(){
return this.prov.find((o) => o.id_provinsi === this.result_estimate.id_location).provinsi
},
}
state.res_estimate have json like this
{
id: 3,
id_location : 2
}
state.prov have json like this
{
id_location : 1
provinsi : canada
},
{
id_location : 2
provinsi : australia
}
i made a function to search province name based on province_id
but my logs get an error
this.prov.find(...) is undefined
but return this.prov.find((o) => o.id_provinsi === 7 (manual param)).provinsi success
why ?

Related

Vue.js filter values from two store

I need help with getters in Vue.js, I'm trying to get list of data that is connected with id in two different stores.
Here is structure:
pageUser {
pageId,
userId,
type,
weight
}
user {
id,
name,
age,
city
}
This is code I have for now:
state: () => {
return {
images: [
{id: '1', name:'John', age: 23, city: 'Boston'},
{id: '2', name:'Jack', age: 34, city: 'Miami'}
]
}
},
getters: {
list: (state, pageId) => (key) => {
return map(state[key], function (s) {
return {
id: s.id,
name: s.name,
age: s.age,
city: s.city
}
})
}
This return me list of all users, but I need to make some filtering, when I go to page for example with id '2586' I need to get list of user that belong that page and they should be sorted by weight.
I'm pretty new in Vue.js and I really don't know how to make this.
getters: {
getUser: state => id => {
return user
// Create a new array of objects merging both the states
.map(u => {
return {
...pageUser.find(pu => pu.userId === u.id),
u
}
})
// Filter by id provided to the getter
.filter(u => u.id === id)
// Sort on basis of weight
.sort((a,b) => {
if (a.weight < b.weight) {
return -1
}
else if (a.weight > b.weight)) {
return 1
}
return 0
})
}
}
Call the getter in your component:
this.$store.getters.getUser('2586')

Set data field from getter and add extra computed field

I wanted to set fields inside data using getters:
export default {
data () {
return {
medications: [],
}
},
computed: {
...mapGetters([
'allMedications',
'getResidentsById',
]),
I wanted to set medications = allMedications, I know that we can user {{allMedications}} but my problem is suppose I have :
medications {
name: '',
resident: '', this contains id
.......
}
Now I wanted to call getResidentsById and set an extra field on medications as :
medications {
name: '',
resident: '', this contains id
residentName:'' add an extra computed field
.......
}
I have done this way :
watch: {
allMedications() {
// this.medications = this.allMedications
const medicationArray = this.allMedications
this.medications = medicationArray.map(medication =>
({
...medication,
residentName: this.getResidentName(medication.resident)
})
);
},
},
method: {
getResidentName(id) {
const resident = this.getResidentsById(id)
return resident && resident.fullName
},
}
But this seems problem because only when there is change in the allMedications then method on watch gets active and residentName is set.
In situations like this you'll want the watcher to be run as soon as the component is created. You could move the logic within a method, and then call it from both the watcher and the created hook, but there is a simpler way.
You can use the long-hand version of the watcher in order to pass the immediate: true option. That will make it run instantly as soon as the computed property is resolved.
watch: {
allMedications: {
handler: function (val) {
this.medications = val.map(medication => ({
...medication,
residentName: this.getResidentName(medication.resident)
});
},
immediate: true
}
}

Vuex assign null conditionally in action

I have this action in my store:
updateTicketCustomer ({commit, state}, selectedCustomer) {
axios.patch('/tickets/' + state.currentTicket.id, {
customer_id: selectedCustomer.id
})
.then((response) => {
commit('UPDATE_TICKET_CUSTOMER', selectedCustomer)
});
}
If I wanted to assign null to customer_id, what is the right way to do it? Given that in template I assign null to selectedCustomer, how do I build the conditional to assign null or selectedCustomer.id?
Something like
if (selectedCustomer !== null) {
customer_id: selectedCustomer.id
} else {
customer_id: null
}
You could use the conditional operator:
updateTicketCustomer ({commit, state}, selectedCustomer) {
axios.patch('/tickets/' + state.currentTicket.id, {
customer_id: selectedCustomer !== null ? selectedCustomer.id : null
})
.then((response) => {
commit('UPDATE_TICKET_CUSTOMER', selectedCustomer)
});
}
The syntax is, basically:
<condition> ? <returned if true> : <returned if false>

How to fast insert a JSON into Realm Database for a React Native App

I'm designing an offline app using React Native and Realm. One of the features is downloading data from the web API before going offline.The downloaded data is a long JSON. For example:
[{"EventID":"3769","EventName":"Birthday Party","EventDate":"Jun 21 2018 4:00 PM"},{"EventID":"4232","EventName":"Homecoming","EventDate":"Jun 22 2018 11:00 PM"}, {"EventID":"3838","EventName":"the Summer Show","EventDate":"Jun 28 2018 2:00 AM"}]
There are many examples of how to insert one entry in Realm, such as:
realm.write(() => {
Event.push({EventID: 3769, EventName: 'Birthday Party'});
Event.push({EventID: 4232, EventName: 'Homecoming'});
});
But is there a way to bulk insert JSON into a Realm table at once?
Many thanks!!!
Update - Works!
I've tried geisshirt's solution (thanks!) with codes below. It takes about 10sec to import a JSON String with 50,000 entities. (Each entity has ID, name and date properties). One trick is that debug mode is much slower than running on the real app.
React Native Code:
axios.get('https://APISERVER/XX/GET_EVENTS')
.then(response => {
Realm.open({
schema: [{ name: 'Events', properties: { EventID: 'string', EventName: 'string', EventDate: 'string' } }]
}).then(realm => {
realm.write(() => {
response.data.forEach(obj => {
realm.create('Events', obj);
});
});
})
Thanks again!
You can do something like:
let objs = JSON.parse('[{"EventID":"3769","EventName":"Birthday Party","EventDate":"Jun 21 2018 4:00 PM"},{"EventID":"4232","EventName":"Homecoming","EventDate":"Jun 22 2018 11:00 PM"}, {"EventID":"3838","EventName":"the Summer Show","EventDate":"Jun 28 2018 2:00 AM"}]');
realm.write(() => {
objs.forEach(obj => {
realm.create('Event', obj);
});
});
You insert all object in one transaction (realm.write()).
Data.js
const DataList= {
list: [
{
"prodId": "4232",
"prodName": "Hero Moto Corp",
"prodDesc": "Allrounder ",
"prodPrice": "15000",
"prodImage": "https://lh3.googleusercontent.com/a-/AAuE7mBq326Bqo0dObU3TDEDK3fBw9kc3PI5J4Tjt9fw=s96-c"
},
{
"prodId": "4232",
"prodName": "Hero Moto Corp",
"prodDesc": "Awesome product",
"prodPrice": "18500",
"prodImage": "https://lh3.googleusercontent.com/a-/AAuE7mBq326Bqo0dObU3TDEDK3fBw9kc3PI5J4Tjt9fw=s96-c"
}
]
}
export default DataList;
// let objs = JSON.parse('[{"prodId":4232,"prodName":"Homecoming","prodDesc":"MBA" , "prodImage": "https://lh3.googleusercontent.com/a-/AAuE7mBq326Bqo0dObU3TDEDK3fBw9kc3PI5J4Tjt9fw=s96-c","prodPrice" : "15236"},{"prodId":4232,"prodName":"Homecoming","prodDesc":"MBA" , "prodImage": "https://lh3.googleusercontent.com/a-/AAuE7mBq326Bqo0dObU3TDEDK3fBw9kc3PI5J4Tjt9fw=s96-c","prodPrice" : "15236"},{"prodId":4232,"prodName":"Homecoming","prodDesc":"MBA" , "prodImage": "https://lh3.googleusercontent.com/a-/AAuE7mBq326Bqo0dObU3TDEDK3fBw9kc3PI5J4Tjt9fw=s96-c","prodPrice" : "15236"},{"prodId":4232,"prodName":"Homecoming","prodDesc":"MBA" , "prodImage": "https://lh3.googleusercontent.com/a-/AAuE7mBq326Bqo0dObU3TDEDK3fBw9kc3PI5J4Tjt9fw=s96-c","prodPrice" : "15236"}]');
import DataList from './Data'
DataList.list.forEach(obj => {
db.addProduct(obj).then((result) => {
console.log(" insert result --------- " + result);
this.setState({
isLoading: false,
});
this.props.navigation.navigate('ProductScreen');
// alert("Sqlite Insert Difference " + difference );
}).catch((err) => {
console.log(" insert err --------- " + err);
this.setState({
isLoading: false,
});
})
});

Redux Update a state with an array of objects

I have a state like this:
this.state ={
photos: [
{ description: 'someDescription', id: 1 },
{ description: 'someDescription', id: 2 },
{ description: 'someDescription', id: 3 }
]
}
How can I update one of the descriptions only?
Or I have to do something like
this.setState({ photos: newArrayOfObjectsWithOnlyOneUpdatedDescription })
You can create a funtion to do it for you like this:
const updatePhoto = (id, desc) =>
this.state.photos.map((obj) =>
obj.id === id ? Object.assign(obj, { description: desc }) : obj)
map function will return a new array, so you won't need to do a manual state cloning stuff.
Then reuse it as you need it:
this.setState({ photos: updatePhoto(2, 'new desc') })
You can create copy of state, then update copied state and setState
let stateCopy = Object.assign({}, this.state); // get the current state copy
stateCopy.photos = stateCopy.photos.slice(); // get photos object
stateCopy.photos[key] = Object.assign({}, stateCopy.photos[key]);
stateCopy.photos[key].description = 'new decription'; // update description of specific key
this.setState(stateCopy); // set state