React Native fetch array json data - react-native

I am pulling data from Mysql to React native. As you can see, the output of the data I have captured is in the array. How can I pull Array data? With the code below, I can pull the data into an array. For example, I want to extract the new_image variable from the array.
getBusinessNewsData() {
fetch('...').then((response) => response.json())
.then((findresponse)=>{
var newSearch = findresponse.new_image;
console.log(newSearch)
this.setState({
data:newSearch,
})
})
[
{
"id":"..",
"new_date":"...",
"new_title":"...",
"new_slug":"...",
"new_url":"",
"new_image":"...",
"new_fixed":"..."
}
]

Map on the response and extract new_image
const result = findResponse.map((d) => d.new_image);
Then you can set result in component internal state.

If the console.log(newSearch) gives you the array above and you want to have the new_image property then you can set a state like this.setState({ newImage: newSearch[0].new_image })
By doing so this.state.newImage would be the value from the array.

Related

How do I split up an array while still selecting all items?

Let's say I have an array of fruits and an empty basket array. I push the fruits to the basket and loop through the basket in the template. I can output the whole array of fruits inside the basket.
<template>
<div v-for="fruit in basket">
<li>{{ fruit }}</li>
</div>
<button #click="addFruit">Add to basket</button>
</template>
<script>
data() {
return {
fruits: ['Orange', 'Apple'],
basket: [],
};
},
methods: {
addFruit() {
this.basket.push(this.fruits);
},
}
</script>
But what if I want each individual fruit to be shown as a list item? As it is right now I output the entire array of fruits.
I know that I can easilly get the individual fruits by saying
<li>{{ fruit[0] }}</li>
But that would not be practical as it requires a lot of manual work.
When I am pushing the fruits, I am looking for a way to also split them up, so that when I fire the addFruit function, I add all the fruits, but I add them as individual items.
I know there are other ways to do this, but I specifially want to know how I do this while keeping the arrays and the push method.
EDIT: I tried to write the fruit example because I wanted to keep it as simple as possible, but I will include my own code then.
In my code, I fetch an array of data from my database. I store the data results in a const called recipients. That is then pushed into an array called defaultTags. So I push an array of data into an empty array, in this case a list of emails and other contact information, which is then outputted as a tag, but what I want is to actually output the data as individual items. So instead of having one big tag that stores the whole array. Eg: [email1, email2, email3], I wish to have a seperate tag for each email in the array.
load() {
switch (this.entityType) {
case 'TENANCY':
userService.getCurrentUser().then(userResult => {
tenancyService.getTenants(this.entityId).then(result => {
const defaultTags = [];
const recipients = result.data
.map(tenant => tenant.legalEntity)
.filter(legalEntity => legalEntity.email || (!legalEntity.email && this.asNotification ? legalEntity.name : null))
.map(legalEntity => ({
emailAddress: legalEntity.email || (!legalEntity.email && this.asNotification ? legalEntity.name.concat(' ', `(${this.$t('letterMail').toLowerCase()})`) : null),
legalEntityId: legalEntity.id
}));
if (recipients.length) {
defaultTags.push(this.setText({description: this.$t('tenants'), recipients}));
}
this.autocompleteItems.push(...defaultTags);
if (this.includeUser) {
defaultTags.push(this.setText({
description: this.$t('user'),
recipients: [{emailAddress: userResult.data.email}]
}));
}
if (this.prefill) {
this.tagsChanged(defaultTags);
}
tenancyService.getUnits(this.entityId).then(result =>
result.data.forEach(unitTenancy => this.addPropertyContactsToAutocompleteItems(unitTenancy.unit.propertyId)));
});
});
break;
case 'UNIT':
unitService.get(this.entityId).then(result =>
this.addPropertyContactsToAutocompleteItems(result.data.propertyId));
break;
case 'PROPERTY':
this.addPropertyContactsToAutocompleteItems(this.entityId);
break;
}
},
I am focusing specifically on this line:
if (recipients.length) {
defaultTags.push(this.setText({description: this.$t('tenants'), recipients}));
}
It outputs the entire fruit items because you are pushing the whole array into the basket array, not the actual items. Saying basket is an array of array, not an array of fruits.
// Instead of this
this.basket.push(this.fruits); // [['Orange', 'Apple']]
// Use array destructuring
this.basket.push(...this.fruits); // ['Orange, 'Apple']
// Or concat
this.basket.concat(this.fruits); // ['Orange, 'Apple']

VUEJS and Vuetify - Push the results from a localbase into a data table

How do i push my results into a data object please
I would like to push the :key to the id field and the :data to map across to my other data fields
my data object is called orgs: []
I have the following data returned from my get query
[{…}]
0:
data: {person: 'John', orgName: 'test', due: 'this is due'}
key: "11ed25ccf7548160bff2ab4c1d56ee40"
I have tried
this.$db.collection('orgs').get({ keys: true })
.then
(response => {
console.log('orgs: ', response) <--- this displays the results
this.orgs.forEach(response => {
const data = {
'person': response.data.person,
'orgName': response.data.orgName,
'due': response.data.due,
'id': response.key
}
this.orgs.push(data)
})
});
I get no errors but my this.orgs data item remains empty so assume I am not updating the array for some reason
Thanks
I seem to be able to populate it in a simple way as follows
this.$db.collection('orgs').get({ keys: true })
.then
(response => {
this.orgs = response
console.log('response:', this.orgs)
})
Is there any issue with this approach for just getting my results or should I be using push?

React Native can not using Spread Operator to update object in array

i have the state that control the flatList data
const [data, setData] = useState([])
i have a object like below(after get from network, it's show success in FlatList)
data = [{
'name' : 1,
},
{'name' : 2,
}]
Now i want to update first object {'name': 1} by add some key/value like this:
{ 'name' : 1, 'text' : 'this is text'}
Here is my code:
const mathched = data[0]
mathched = [
...mathched,
{'text': 'this is text'}
]
But i got error: TypeError: "mathched" is read-only
I tried other solution by set new key to object:
const newData = [...data]
const mathched = newData[0]
mathched['text'] = 'this is text'
setData(newData)
But data not changed
Can someone guide me how to use Speard Operator to done my solution? Thanks
The problem is that the state value is a read-only variable that can be modified only via the setter, setData in this case.
When you do const matched = data[0] then matched = newData[0] you are attempting to store the new value without the setter usage.
One way to go would be:
// Usign for example Lodash clone
const newClonedData = clone(data);
newClonedData[0] = { ...matched[0], {'text': 'this is text'} };
setData[newClonedData];

Ramda - extract object from array

I am trying to filter an array of objects with Ramda and it is working almost as I planned but I have one small issue. My result is array with one filtered object which is great but I need only object itself not array around it.
My example data set:
const principlesArray = [
{
id: 1,
harvesterId: "1",
title: "Principle1"
},
{
id: 2,
harvesterId: "2",
title: "Principle2"
},
]
And that is my Ramda query:
R.filter(R.propEq('harvesterId', '1'))(principlesArray)
As a result I get array with one filtered element but I need object itself:
[{"id":1,"harvesterId":"1","title":"Principle1"}]
Any help will be appreciated
You can use R.find instead of R.filter, to get the first object found:
const principlesArray = [{"id":1,"harvesterId":"1","title":"Principle1"},{"id":2,"harvesterId":"2","title":"Principle2"}]
const result = R.find(R.propEq('harvesterId', '1'))(principlesArray)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>
A more generic approach would be to create a function that takes a predicate used by R.where, pass the partially applied R.where to R.find, and then get the results by applying the function to the array:
const { pipe, where, find, equals } = R
const fn = pipe(where, find)
const principlesArray = [{"id":1,"harvesterId":"1","title":"Principle1"},{"id":2,"harvesterId":"2","title":"Principle2"}]
const result = fn({ harvesterId: equals('1') })(principlesArray)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>

data change doesn't reflect in vue application

In my Vue application I am trying to create a simple table with changeable column sequence. In the data structure I keep all column data with its thead. I use compute to calculate rows from column data using matrix transposion. However any change I do to dynamicTable.columns doesn't reflect in the view.
function transpose(a)
{
return a[0].map(function (_, c) { return a.map(function (r) { return r[c]; }); });
// or in more modern dialect
// return a[0].map((_, c) => a.map(r => r[c]));
}
var tData = {
columns:[
{thead:'isbn',
tdata:[1,2]},
{thead:'name',
tdata:['rose','flower']},
{thead:'price',
tdata:['10','15']},
{thead:'author',
tdata:['john','jane']},
{thead:'page count',
tdata:['396','149']},
{thead:'print date',
tdata:['2001', '1996']}
]
}
var dynamicTable = new Vue({
el: '#dynamicTable',
data: tData,
computed:{
rows: function(){
arr = [];
this.columns.forEach(function(element){
arr.push(element.tdata);
});
return transpose(arr)
}
}
})
For example I want to change the order of isbn column with price,
a=dynamicTable.columns[0]
b=dynamicTable.columns[2]
dynamicTable.columns[0]=b
dynamicTable.columns[1]=a
data changes but changes are not reflected. What is the problem here?
As mentioned in the documentation, this is a JavaScript limitation. Direct changes to an array are not detected by Vue.
One workaround for this, is to use Vue.set(), as instructed in the link.