Angular: Cannot read property 'length' of undefined

When I write to my database, I get the following error.

ERROR TypeError: Cannot read property ‘length’ of undefined

The error is at

for (i = 0; i < this.myObject.length; i++) {

The rest of the code is:

this.route.queryParams.subscribe(params => {

const checkoutRef = this.db.list('cart_checkouts');
var i;
var myObject;
for (i = 0; i < this.myObject.length; i++) {
	checkoutRef.push({ checkoutProductName : this.myObject[i].product_name, checkoutProductPrice: this.myObject[i].product_price, checkoutQuantity : this.myObject[i].quantity, checkoutThumbnail : this.myObject[i].thumbnail });
}
});

The funny thing is, this used to work even with the error but now it doesn’t write to the database at all.

The query parameters are:
id, thumbnail, quantity, product_name, product_price

what’s the value of this?

It has no value. It’s an empty array. It can also be initialized as


var myObject = [];

the variable myObject is not the same as this.myObject and if this.myObject doesn’t exist then you can’t read its length property

I removed the this and changed it to:

var myObject = [];
for (i = 0; i < myObject.length; i++) {
	checkoutRef.push({ checkoutProductName : myObject[i].product_name, checkoutProductPrice: myObject[i].product_price, checkoutQuantity : myObject[i].quantity, checkoutThumbnail : myObject[i].thumbnail });
}

but it still doesn’t work. The error message goes away but it doesn’t write to the database.

In the code above you have set myObject as an empty array, so the loop is over a length of 0 and nothing will happen.

When I remove the empty array, I get the error message again and it still doesn’t work.

Where is the myObject data coming from? It needs to be defined somewhere and passed into this function for this function to work.

myObject isn’t defined anywhere except in the function that I showed.

Then a loop over it’s contents will do the exact same thing every time based on the hardcoded contents of that variable.

What is the intended purpose of this function?

I’m trying to write to the database.

Ok, where is the data you are trying to write to the database coming from?

It’s coming from the query parameters.

So where is the myObject coming from? Why was it added?

It looks like the query params contain everything you need without making a loop over a dummy myObject.

1 Like

I did the following and there were no errors but it didn’t write to the database:

this.route.queryParams.subscribe(params => {
const checkoutRef = this.db.list('cart_checkouts');
var i;
for (i = 0; i < params.length; i++) {
	checkoutRef.push({ checkoutProductName : params[i].product_name, checkoutProductPrice: params[i].product_price, checkoutQuantity : params[i].quantity, checkoutThumbnail : params[i].thumbnail });
}
});

This isn’t writing to the database.


ngOnInit() {

this.route.queryParams.subscribe(params => {

const itemsRef = this.db.list('cart_checkouts');
itemsRef.push({checkoutProductName : this.product_name });

});
}

I get the error:

Error: Reference.push failed: first argument contains undefined in property ‘cart_checkouts.checkoutProductName’

The query parameters are:
id, thumbnail, quantity, product_name, product_price

so product_name should be available to write to the database.

When I write

itemsRef.push({checkoutProductName : "Helmet" });

It saves “Helmet” to the database so I know that the error is in this.product_name.

Ok so I’m not super familiar with the API’s you’re using as I’m primarily use PHP in the backend (I’m guessing MongoDB with Mongoose maybe?)

But I see a couple problems.

First myObject isn’t initialized to anything so myObject.length wouldn’t work.

As pointed out in another comment this.myObject doesn’t reference anything which is why the length of undefined error but you figured that out already.

Even if you initialize the variable like var myObject = []; it’s still just an empty array so you’re loop isn’t going to work.

myObject also isn’t an array of objects so myObject[i].anything wouldn’t work since there’s no object at myObject[i].

I’m not sure what the shape of params is but what you might be looking for is something close to this:

this.route.queryParams.subscribe(params => {

const checkoutRef = this.db.list('cart_checkouts');

checkoutRef.push({ 
    checkoutProductName: params.product_name, 
    checkoutProductPrice: params.product_price, 
    checkoutQuantity: params.quantity, 
    checkoutThumbnail: params.thumbnail 
});

Let me know if that works :slight_smile:

Thanks, dannyjamesfletcher

I tried that and got the same error: Reference.push failed: first argument contains undefined in property ‘cart_checkouts.checkoutProductName’

I have a form that sends the query parameters like this:

<form [formGroup]="submitForm" (ngSubmit)="checkOut(items)">
<input type="submit" value="Check Out">
</form>

public checkOut(items: any)  {
{ this.router.navigate(['check-out'], { queryParams: { checkouts: JSON.stringify(this.items) } });

and when I write this:

itemsRef.push({checkoutProductName : params['checkouts'] });
It gets the entire array of checkout items and saves it to checkoutProductName.

The query parameters in the url field look like this:

http://localhost:4200/check-out?checkouts=%5B%7B%22id%22:1,%22thumbnail%22:%22product-2.gif%22,%22quantity%22:2,%22product_name%22:%22Adult%20Female%20Bike%22,%22product_price%22:20.5%7D,%7B%22id%22:3