I have a function in JSX that stores value gotten from a database thus:
const data = JSON.parse(xhr.responseText);
this.setState({ data: data });
The response format is:
[{"id":4,"name":"Avengers: Infinity War","year":2018},{"id":5,"name":"Thor: Ragnarock","year":2017},{"id":6,"name":"Black Panther","year":2018},{"id":7,"name":"Star Wars: The Rise of Skywalker","year":2019}]
However, I am trying to use a react table control that expects the data to be in this format:
const data = [
['1st column', '2nd column', '3rd column'],
['1st cell', '2nd cell', '3rd cell']
]
render() {
<ReactTabllist
data={data}
property={property} />
}
So I need to turn the JSON into an javascript array of arrays. What is a good way to do this?
const data = this.state.data.map(movie => ( /* what goes here? */ ));
As per I understand, you need to get every property in the JSON and then put the values of every element into the data-react property.
So, first you would need to make sure, the response from the database is well formatted, and that every element in the json-parsed responseText is the same as the rest of them.
With that into account:
const formattedData = this
.state
.data
.map(movie => Object.keys(movie).map(key => movie[key]));
And that formattedData is what you want to pass as react-attribute of data={formattedData}
Alternatively, if you don't care about the keys of the movie whatsoever, you could do as #Madmadi has suggested:
const formattedData = this
.state
.data
.map(movie => Object.values(movie));
Related
I have two TaskList components that use the same query GET_TASKS.
Both use a different filter query variable which is passed down to them in props as queryVars.
I defined a standard merge function in type policies to merge the incoming and existing data together.
The TaskList component uses
const { data, fetchMore } = useQuery<Response, Variables>(GET_TASKS, { variables: queryVars })
to retrieve the data.
A Fetch more button has () => fetchMore({ variables: queryVars }) in the onClick attribute.
When I click on the Fetch more button on the left, the tasks on the right get updated as well, however, without its filter applied, so the data that come with Assigned to me filter are also put to the Assigned by me task list and vice versa.
The merge function basically rewrites every data object that uses the given query.
How do I tell Apollo to only update the data that is bound to the component where fetchMore is defined?
You should be able to add filter to the keyArgs property. This should create different cache results based on the filter.
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
tasks: {
keyArgs: ["filter"],
merge(existing, incoming, { args: { offset = 0 }}) {
//Custom merge
},
},
},
},
},
});
i have this structure, in it there is an json object and that object have an array of json objects
i need to ask to them if color1 is red for example btw
name:carla
data: {
sign: "carly",
tools: [{trait:color1, value:red}, {trait:color2, value:white}] }
},
name:dany
data: {
sign: "dan",
tools: [{trait:color1, value:blue}, {trait:color2, value:black}]
}
so i want to get only the elements have color1 red, in this case only should i get first one element
i tried with this
query = query.where('data.tools', "array-contains", {trait: 'color1', value: 'red'})
Your query fetches documents where data.tools contains that object. It does not filter that array. You'll need to parse that object yourself after fetching the docs:
const qSnap = await query.get();
qSnap.docs.forEach((doc) => {
const item = doc.data().data.tools.find(t => t.trait === 'color1' && t.value == 'red');
console.log(item)
})
If you are trying to find a specific tool in a document, then you can create a sub-collection for tools. That way, you can query for one specific and also update it directly if required.
I have the following Mongo Schema which has an array of objects inside of 'balance':
const SubmitDebtSchema = new Schema ({
balance: [{
balanceDate: Date,
newBalance: Number
}],
});
An example console.log of said Schema would then be like this:
balance: Array [
{
id: "20304929403048fd636",
balanceDate: "2020-11-23T10:57:58.845Z",
newBalance: 300
},
{
id:"20fhdjfjwjh39g9395",
balanceDate: "2020-11-23T11:54.58.845Z",
newBalance: 200
} ]
I then have an Axios call which sets an array state like follows:
componentDidMount() {
axios.get("/api/fetch/fetchDebtCards")
.then((response) => {
this.setState({
debts: response.data
})
console.log(this.state.debts)
})
}
Finally, I have the following function which I'm attempting to use to render the results on my web page.
const fetchDebts = this.state.debts.map (debt => {
return (
<IndividualDebtCard key={debt._id}
balance={debt.balance[debt.balance.length - 1][2]}
/>
)
})
This maps through my database, and is attempting to pull the last balance entry to render as props on my web page.
From this last balance entry, I then want to pull the newBalance figure to render in my webpage. So in this example, balance would equal 200.
However, the array.length isn't working. I can't seem to access the last newBalance in my array.
I have simplified my call as it also pulls other entry details, but for simplicity's sake I have removed them. The rest of the call works fine! So it's not a problem with anything else, just getting the last value in the array.
Can anyone point out what I'm doing wrong here?
I think the error is happening because you are using array of objects and trying to get the second index from balance object. For example balance[1][2] is undefined because you can't access objects by index. You can only access objects by key. You can try using balance[1].newBalance if that solves it.
const fetchDebts = this.state.debts.map (debt => {
return (
<IndividualDebtCard key={debt._id}
balance={debt.balance[debt.balance.length - 1].newBalance}
/>
)
})
I have an array of objects (here is only one but thats does not matter) in my JSON "dummy" back end.
In each object I have a property "tags" which also contains simple array, let me show you an example
[
{
"title": "Get up and run",
"author": "Johnny",
"tags": ["react", "javascript"]
}
]
I tried to map an array which gave me a result: (see the code)
Article title: Get up and run
Writer: Johnny
Tags: reactjavascript
but i want to get result like that:
Article title: Get up and run
Writer: Johnny
Tags: react javascript (or "react, javascript" or "#react #javascript")
it seems I can't map "tag" array and main array of objects correctly same time. :(
can u help me?
class Content extends Component {
state = {
posts: []
}
componentDidMount () {
axios.get("json-file.json")
.then(response => {
this.setState({posts: response.data.map(post => {
return post; /*here I get the whole data from dummy
backend */
})})
}
)
}
render () {
const post = this.state.posts.map(post => {
return <Post
title={post.title}
date={post.date}
author={post.author}
tags={post.tags.map(xTag => {
return xTag ;
})} /* I have other Component which correctly renders this...
no worries here */
/>
})
return (
<div>
{post}
</div>
)
}
}
I expect the better "map" of array
I try to get result like this
Article title: Get up and run
Writer: Johnny
Tags: react javascript (or "react, javascript" or "#react #javascript")
instead of
Tags: reactjavascript
or
Tags: ["react", "javascript"] (it was the worst version :)(its fixed ;) ) )
I want to map an array of objects and 'tags' array at same time and correctly,
How can I do that?
Doing tags={post.tags.map(xTag => { return xTag ; })} is equivalent to tags={post.tags}. So the relevant code that affects the final formatting is in Post component. So could either do tags.join(', ') or tags.map(t => '#'+t).join(' ').
You can create a separate component for tag and style it.
Then rewrite this line:
tags={post.tags.map(xTag => {
return <Tag>{xTag}</Tag>; // or <Tag content={xTag} />
})}
If you want to convert your tags array into a string there are several options depending on your desired format:
Using a simple join your formatting is limited: (You can pass in characters which will be appended after every entry e.g .join(' ') for only spaces)
post.tags.join() // Returns 'react,javascript'
Using the reduce function you have further control over how your string will be formatted:
post.tags.reduce((string, tag) => string += `${tag} `, '')
To change the format just edit the string which is attached ${tag}
What I am trying to do
I am creating a social media app with react native and firebase. I am trying to call a function, and have that function return a list of posts from off of my server.
Problem
Using the return method on a firebase query gives me a hard to use object array:
Array [
Object {
"-L2mDBZ6gqY6ANJD6rg1": Object {
//...
},
},
]
I don't like how there is an object inside of an object, and the whole thing is very hard to work with. I created a list inside my app and named it items, and when pushing all of the values to that, I got a much easier to work with object:
Array [
Object {
//...
"key": "-L2mDBZ6gqY6ANJD6rg1",
},
]
This object is also a lot nicer to use because the key is not the name of the object, but inside of it.
I would just return the array I made, but that returns as undefined.
My question
In a function, how can I return an array I created using a firebase query? (to get the objects of an array)
My Code
runQ(group){
var items = [];
//I am returning the entire firebase query...
return firebase.database().ref('posts/'+group).orderByKey().once ('value', (snap) => {
snap.forEach ( (child) => {
items.push({
//post contents
});
});
console.log(items)
//... but all I want to return is the items array. This returns undefined though.
})
}
Please let me know if I'm getting your question correctly. So, the posts table in database looks like this right now:
And you want to return these posts in this manner:
[
{
"key": "-L1ELDwqJqm17iBI4UZu",
"message": "post 1"
},
{
"key": "-L1ELOuuf9hOdydnI3HU",
"message": "post 2"
},
{
"key": "-L1ELqFi7X9lm6ssOd5d",
"message": "post 3"
},
{
"key": "-L1EMH-Co64-RAQ1-AvU",
"message": "post 4"
}
...
]
Is this correct? If so, here's what you're suppose to do:
var items = [];
firebase.database().ref('posts').orderByKey().once('value', (snapshot) => {
snapshot.forEach((child) => {
// 'key' might not be a part of the post, if you do want to
// include the key as well, then use this code instead
//
// const post = child.val();
// const key = child.key;
// items.push({ ...post, key });
//
// Otherwise, the following line is enough
items.push(child.val());
});
// Then, do something with the 'items' array here
})
.catch(() => { });
Off the topics here: I see that you're using firebase.database().... to fetch posts from the database, are you using cloud functions or you're fetching those posts in your App, using users' devices to do so? If it's the latter, you probably would rather use cloud functions and pagination to fetch posts, mainly because of 2 reasons:
There might be too many posts to fetch at one time
This causes security issues, because you're allowing every device to connect to your database (you'd have to come up with real good security rules to keep your database safe)