Array length is zero but Array is not empty - javascript

When I'm trying to iterate through an array, get it's length or access indexes I'm getting Error TypeError: Cannot read property 'map' of undefined.
The array isn't empty and when I console.log() it I've gotten.
0: {user_id: 11, …}
length: 1
__proto__: Array(0)
I see that proto: Array(0) and I'm assuming this means it's a 0 length Array but how do I make it non-zero length so that I can iterate through it?
Code for reference:
useEffect(() => {
blog.authors.map(data => {
console.log(data)
})
}, [blog])
I've also tried. It worked, but I immediately got the similar error.
useEffect(() => {
(async() => {
await blog.authors.map(data => {
console.log(data)
})
})()
}, [blog])

The simple checking if blog.authors isn't undefined solved it.

No, array indexes are 0 based.
var arr = ['a', 'b'];
console.log(arr.length); // => 2
console.log(arr[0]); // => a
So instead of making confusing assertion about what works and not without providing the code them providing other code, could you just see the result of that:
useEffect(() => {
console.log({blog});
console.log({authors: blog.authors });
blog.authors.map(data => {
console.log(data)
})
}, [blog])
Because I suspect that blog changed overtime, having some authors and something authors undefined.

Related

Reduce function returning NaN when pulling object from array - MongoDB database, React frontend

I have the following Schema:
const SubmitDebtSchema = new Schema ({
balance: [{
balanceDate: Date,
newBalance: Number
}],
});
I am attempting to loop through my database entries, pull the 'newBalance' out from each object in the balance array, and then reduce / sum them together.
However, it is returning 'NaN' - and I can't figure out why.
Here is my Axios call to get the data:
componentDidMount() {
axios.get("/api/fetch/fetchDebtCards")
.then((response) => {
this.setState({
debts: response.data
})
console.log(this.state.debts.balance.newBalance)
})
}
The console log in there successfully retrieves the database entries.
And here is my reduce function:
const sumBalance = this.state.debts.reduce(function(previousValue, currentValue) {
return (
previousValue + currentValue.balance.newBalance
)
}, 0)
You can see, I'm attempting to tap into 'balance.newBalance' to access the newBalance within each of the balance objects.
Can anyone point out what I'm doing wrong?
EDIT: My console log, with two entries. What I want to do is get the newBalance array.length -1 from these, and sum them together by reducing.
[Log] Array
0 Object
balance: [{_id: "5fbbddd1077c56000828973c", balanceDate:
"2020-11-23T16:05:36.124Z", newBalance: 400}]
1 Object
balance: [{_id: "5fbc06f58b2f98000865df54", balanceDate:
"2020-11-23T19:01:07.789Z", newBalance: 300}] (1)
if "console.log(this.state.debts.balance.newBalance)" works then debts is not an array, how are you using map on debts then? Map can only be used on arrays.
I'm not sure how your debts object/array is exactly. Maybe a log of it would be helpful.
If it is an array, then this might work.
const sumBalance = this.state.debts.map(x => x.balance).flat().reduce((a,b) => a + b.newBalance, 0)
whereas if it's an object, then this might work
const sumBalance = this.state.debts.balance.reduce((a,b) => a+b.newBalance, 0)
If none of these work, just log "this.state.debts" and let us see what you have there.
Edit: Ok so you only need the last values of the balance arrays (the latest balance), something like this?
const sumBalance = this.state.debts.map(x => x.balance[x.balance.length-1].newBalance).reduce((a,b) => a + b, 0)

Access Array Inside Object

I have a javascript object and I want to map through one of its properties which is an array. But for some reason when I map through it or even call .length on the property which I know is an array it treats the property as if it's not an array.
Object is being created from an axios get request in an asynchronous object.
useEffect(() => {
async function fetchData() {
const dummyData = await axios.get(
'http://localhost:3000/data',
);
dummyData.data.videos.map(video => {
return (
setCurrentEdition(video.currentEdition[0])
);
});
}
fetchArtPiece();
return () => console.log('clean artPiece detail page');
}, []);
currentEdition: {
videoAssociated: {id: "oYu5J4TQbJ728c45ExWopZicY9LrCxNNTEZ3"}
bids: []
id: "Kr3fjeo51"
owners: (2) [{…}, {…}]
}
All im trying to do for now is .map() and it throws an undefined error
currentEdition.owners.map(owners => console.log(owners))
even when i check currentEdition.owners.length it throws an undefined error and when I log currentEdition.owners the proto: is an array and it has the square brackets and everything so why is this not being treated as an array when I try to operate on it?
Thank You
Well, since you are working with asynchronous data you should always make sure that you have your data and then start playing with it around.
So to fix this you need to make a condition for your JSX like this:
<Grid item xs={7}> {Array.isArray(currentEdition?.owners) && console.log(currentEdition.owners.length)} </Grid>

fetch gives me a full array but it is empty when i try to access it

I get an object from a Symfony rest API. This object has a property "shooting" which is an array and this array is full when I console.log it but when i try to access it, it is empty
This is my fetch request
const getProjectsAvailable = async () => {
const data = await fetch(
`${process.env.GATSBY_CORE_URI}/api/dashboard/supplier/projects/available`,
{
headers: {
[`X-Auth-Token`]: `${token}`,
[`Accept`]: `application/json`,
},
}
);
return data;
};
Here is the project object that i get back from fetch request
0: {id: 258, name: "Project26-1", reference: "A6568", isOfferValidated: null, source: "dashboard", …}
It has a shooting key which contains an array and it is not empty
shootings: Array(1)
0:
addressCity: "Paris"
addressCountry: {id: 76}
But when i set this object to my component state, all values stay the same except the shooting key which becomes an empty array
const [projects, setProjects] = useState([]);
useEffect(() => {
getProjectsAvailable().then(res =>
res.json().then(data => {
setProjects(data);
})
);
}, []);
I have no idea why does it act like that.
Thanks in advance
EDIT :
For example, the first line with console.log gives me the response object with a full shooting array while the second one sets it to my state but shooting array is empty
useEffect(() => {
getProjectsAvailable().then(response => console.log(response));
getProjectsAvailable().then(response => setProjects(response));
}, []);
Ok it is my bad. Somewhere else in the code, there was a .split() on the shooting property which mutates the array so the props changed and shooting array got empty

Typescript TypeError: Cannot read property 'collection' of undefined

I'm getting an error of 'collection' undefined when trying to push object.
groupShortlists(lists: ProductShortlist[]) {
const grouped = lists.reduce((groupedList, list) => {
groupedList[list.collection] = [...groupedList[list.collection] || [], list];
return groupedList;
}, {});
return Object.keys(grouped).map(key => grouped[key]);
}
this.shortlistsCategory = [];
this.groupShortlists(this.shortLists).map((item, key) => {
this.shortlistsCategory.push({
collection: item[key].collection,
list: [],
});
});
The exact error says:
TypeError: Cannot read property 'collection' of undefined
Is this the proper way of using push. Any help would be appreciated. :D
In this scenario, the item is already the value at the index key of shortLists. You can do either item.collection or shortLists[key].collection, but not both.
Also, using .map already returns the specified object, so there's no need to use .map and a .push (it's not as semantic).
Below is an example setting shortlists category to the .map return value.
this.shortlistsCategory = this.groupShortlists(this.shortLists)
.map(item => {
return {
collection: item.collection,
list: []
};
});
Link to .map docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

What's is this behavior of JavaScript Array?

I'm started to work with JavaScript/Firestore for a few days but i'm facing some issues with the behavior of the laguage in array's. I cannot run array's with a for loop inside a function and almost all the time it returns me an undefined. this is my code:
This is the code who takes all the id's on firestore who the meeting is active :
function validation () {
let path = firebase.firestore()
path
.collection('database')
.doc('405')
.collection('meetings')
.where('active', '==', true)
.get().then( snapshot =>{
snapshot.docs.forEach( snapshot => {
this.id_firestore.push(snapshot.id)
})
})
},
And this is the code who runs all the id's on id_firestore array and takes all the doubts of the meeting on firestore:
function search_doubts (){
let data = this.id_firestore // in this line data.value = ["QEq1VexdC28BbWRvSFL7","vFsSdDeHJqJQU13dwMwQ"]
let path = firebase.firestore().collection('database').doc('405').collection('meeting')
console.log(data) // here it logs me all the array normally
console.log(data[0]) // here the log returns me undefined
for (let i = 0; i<data.lenght; i++) {
path.doc(data[i]).collection('doubts').get().then( snapshot =>{
snapshot.docs.forEach( snapshot => {
this.doubts.push(snapshot.data().txt_doubts)
this.id_firestore_doubts.push(snapshot.id)
})
console.log(data[1]) //here it logs me the data normally
})
}
}
I did too many searchs but i didn't find anything about this behavior, can anybody answer why the function is behaving like this?
This is the chrome console result's on my debbug:
Console.log(data):
[__ob__: Observer]
0: "QEq1VexdC28BbWRvSFL7"
1: "vFsSdDeHJqJQU13dwMwQ"
length: 2
__ob__: Observer {value: Array(2), dep: Dep, vmCount: 0}
__proto__: Array
Console.log(data[0]):
undefined
Console.log(data[1])
vFsSdDeHJqJQU13dwMwQ
Found the answer. I'm did this functions in a vue enviorment and because and under the table the variable runs observer standards. I Just have to make a internal var and run the other function inside it:
function validation () {
let id_firestore = []
let path = firebase.firestore()
path
.collection('database')
.doc('405')
.collection('meetings')
.where('active', '==', true)
.get().then( snapshot =>{
snapshot.docs.forEach( snapshot => {
this.id_firestore.push(snapshot.id)
})
this.search_doubts (id_firestore)
})
},
Thank's for the help!

Categories

Resources