Cannot read property 'slice' of undefined on class Cart - javascript

I have a problem with some class for cart , which I must use in my work.
Here is code of this class:
class Cart {
constructor() {
this.key = "IT_SPA_CART";
if (!this.exists()) {
this.setItSpaCart([]);
}
}
get() {
const cookies = document.cookie.split(";");
return cookies.find(cookie => cookie.startsWith(this.key));
}
exists() {
return this.get() !== undefined;
}
getItSpaCart() {
const cookieValue = this.get().slice(12);
const parsedValue = JSON.parse(cookieValue);
return parsedValue;
}
setItSpaCart(value) {
const stringifiedValue = JSON.stringify(value);
document.cookie = `${this.key}=${stringifiedValue}`;
}
add(item) {
const cartValue = this.getItSpaCart();
this.setItSpaCart([...cartValue, item]);
}
remove(item) {
const cartValue = this.getItSpaCart();
const itemInCart = cartValue.findIndex(val => val.name === item.name);
if (itemInCart !== -1) {
cartValue.splice(itemInCart, 1);
this.setItSpaCart(cartValue);
}
}
}
When I try to use this class, e.g. with method add(), like this:
let cart = new Cart();
cart.add([{ num: 1, cost: 2 }, { num: 3, cost: 4 }, { num: 5, cost: 6 }]);
this error occur:
Cannot read property 'slice' of undefined at Cart.getItSpaCart
Why this is happend?
Thanks for every hint.

I had the same problem ;-) Maybe You already know how to fix it, but if not, perhaps solution is changing code in this line: const cookies = document.cookie.split(";");. I changed ("; ) into ("; ").

Related

TypeError: Cannot read properties of undefined (reading 'vin')

For some reason I have variables outside of my function and I'm updating that variable in my function but when I call that variable in another function I get a undefined typeError
let bikeShare = []
let stations = []
function startRide(vin) {
bikeShare = bikeShare.map((bike) => {
bike.vin === vin ? { ...bike, checkOut: true } : bike
})
return {}
}
function endRide(vin) {
console.log(bikeShare)
bikeShare = bikeShare.map((bike) => {
bike.vin === vin && bike.checkOut
? { ...bike, checkOut: false, totalRides: bike.totalRides + 1 }
: bike
})
return {}
}
function createBike(color = 'red') {
const vin = bikeShare.length + Date.now();
const payload = { vin, color, checkOut: false, totalRides: 0 }
bikeShare.push(payload);
return payload
}
const bike_1 = createBike('red')
const bike_2 = createBike('blue')
const bike_7 = createBike('green')
startRide(bike_1.vin) // in the startRide function I get an array [undefined, undefined, undefined]
endRide(bike_1.vin)
You are in the startRide() function not returning the result of each assignment in the .map method, so it returns undefined which why you see the array of undefined values.
This should fix it:
let bikeShare = []
let stations = []
function startRide(vin) {
bikeShare = bikeShare.map((bike) => {
return bike.vin === vin ? { ...bike, checkOut: true } : bike
})
return {}
}
function endRide(vin) {
console.log(bikeShare)
bikeShare = bikeShare.map((bike) => {
bike.vin === vin && bike.checkOut
? { ...bike, checkOut: false, totalRides: bike.totalRides + 1 }
: bike
})
return {}
}
function createBike(color = 'red') {
const vin = bikeShare.length + Date.now();
const payload = { vin, color, checkOut: false, totalRides: 0 }
bikeShare.push(payload);
return payload
}
const bike_1 = createBike('red')
const bike_2 = createBike('blue');
const bike_7 = createBike('green');
startRide(bike_1.vin) // in the startRide function I get an array [undefined, undefined, undefined]
endRide(bike_1.vin)
To lift this out of comment, the body of the map argument function in startRide is enclosed in curly braces. You could remove the braces or put return bike inside the braces to stop it returning undefined.
However, setting bike.vin to a bike "payload" object with checkout set to true, leaving bike.checkout set to false, is a bug. One solution might be to use find instead of map:
let bikeShare = []
let stations = []
function startRide(vin, start = true) {
const bike = bikeShare.find(bike=>bike.vin === vin);
if( bike) {
bike.checkOut = start;
}
return bike; // for debugging
}
function endRide(vin) {
return startRide( vin, false);
}
function createBike(color = 'red') {
const vin = bikeShare.length + Date.now();
const payload = { vin, color, checkOut: false, totalRides: 0 }
bikeShare.push(payload);
return payload
}
const bike_1 = createBike('red')
const bike_2 = createBike('blue')
const bike_7 = createBike('green')
console.log( startRide(bike_1.vin));
console.log( endRide(bike_1.vin));

Cannot read property 'push' of null in angular 9

i get flat list from server and i must create a tree that list .
this is my model :
export interface ClaimManagerList {
id: number;
title: string;
parentId: number;
isChilde: boolean;
childs: Childes[];
}
export interface Childes {
id: number;
title: string;
parentId: number;
isChilde: boolean;
}
and in this code i convert flat list to tree list -> childs add to this property childs :
return this.claimsManagerService.getAll(this.searchParam).pipe(
map(data => {
data['records'].forEach(element => {
let model = {} as ClaimManagerList;
if (element.parentId == null) {
model.id = element.id;
model.isChilde = element.isChilde;
model.parentId = element.parentId;
model.title = element.title;
data['records'].forEach(child => {
if (child.parentId == element.id) {
let childe = {} as Childes;
childe.id = child.id;
childe.isChilde = child.isChilde;
childe.parentId = child.parentId;
childe.title = child.title;
model.childs.push(childe)
}
})
this.claims.push(model)
}
})
return this.claims;
})
but it show me error in this line :
model.childs.push(childe)
Cannot read property 'push'
whats the problem ? how can i solve this problem ?
This happening as model.childs is not set to an empty array at the beginning. We can resolve this like:
if(!model.childs) model.childs = [] as Childes[];
model.childs.push(childe) // This line should work fine now.
I'm going to propose some changes to your code to order to improve this. I hope these changes will be useful for you.
return this.claimsManagerService.getAll(this.searchParam).pipe(
map((data: any) => {
data.records.forEach((element: any) => {
let model: ClaimManagerList = {};
if (element.parentId == null) {
model.id = element.id;
model.isChilde = element.isChilde;
model.parentId = element.parentId;
model.title = element.title;
model.childs = [];
data.records.forEach((child: any) => {
if (child.parentId == element.id) {
let childe = {} as Childes;
childe.id = child.id;
childe.isChilde = child.isChilde;
childe.parentId = child.parentId;
childe.title = child.title;
model.childs.push(childe)
}
})
this.claims.push(model)
}
})
return this.claims;
})

Setting a variable equal to a return of function

I'm trying to set a variable equal to a return of a function but I don't understand how can i do.
In particular this is the code:
constructor() {
super();
this.manager = new BleManager()
this.state = {
info: "",
values: {}
}
this.deviceprefix = "FM_RAW";
this.devicesuffix_dx = "DX";
}
model_dx(model) {
return this.deviceprefix + model + this.devicesuffix_dx
}
if (device.name === "THERE i should use the return of model_dx") {
this.info(device.id)
this.manager.stopDeviceScan();
device.connect()
I should check device.name with the result of the model_dx function. How can I do?
Thank you
How about calling it? Create a instance of the object and call it:
// Assume the name is CustomObj
class CustomObj {
constructor() {
super();
this.manager = new BleManager()
this.state = {info: "", values: {}}
this.deviceprefix = "FM_RAW";
this.devicesuffix_dx = "DX";
}
model_dx(model) {
return this.deviceprefix + model + this.devicesuffix_dx
}
}
// I suppose this is outside of the object? Otherwise it would be out of scope anyways as you wrote your if in no function or whatsoever
CustomObj obj = new CustomObj(); //<-- Create instance
let alwaysdifferentParam = "model test";
if (device.name === obj.model_dx(alwaysdifferentParam )) { //<-- Call it
this.info(device.id)
this.manager.stopDeviceScan();
device.connect()
}
Try this:
if (device.name === this.model_dx('pass the desired value here')) {
this.info(device.id)
this.manager.stopDeviceScan();
device.connect()
}

ES2015 + flow : self-referenced (circular ?) enums

Using rollup, buble, flow-remove-types,
Is it possible to create an ENUM of classes instances for chess board representation, as types, like this:
// a Ref is a class or a type
class Ref { /* ... */ }
// Refs is an ENUM
Refs.forEach((ref: Ref, key: string) => {
console.log(key) // outputs: "a1", ..., "h8" successively
})
// type checking should work
typeof Refs.a1 === Ref // true
// etc...
typeof Refs.h8 === Ref // true
// move(ref) --> ref will work
Refs.a1.move(7, 7) === Refs.h8 // true
Refs.h8.move(-7, -7) === Refs.h8 // true
// with...
Refs.a1.move(0, 0) === Refs.a1 // true
// void reference
Refs.a1.move(-1, -1) === null
// or
Refs.a1.move(-1, -1) === Refs.EMPTY
A possible modular implementation would be packing the Ref class and the Refs collection in the same file, with a initialization code, like Enuify lib does... But how to make the Ref#move method working properly ??
The same as :
TicTacToe.X.us =TicTacToe.X
TicTacToe.X.them =TicTacToe.O
TicTacToe.O.us =TicTacToe.O
TicTacToe.O.them =TicTacToe.X
something like this, is perfectible, but works fine for me...
type TF = 'a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'
type TR = '1'|'2'|'3'|'4'|'5'|'6'|'7'|'7'
type TRefDef = {
file: TF,
fidx: number,
rank: TR,
ridx: number
}
interface IRef {
move (df: number, dr: number) : IRef
}
const FILES: Array <TF> = 'abcdefgh'.split('')
const RANKS: Array <TR> = '12345678'.split('')
const all: {
[key:string] : IRef
} = {}
const compute = function(fidx: number, ridx: number): IRef {
const file: TF = FILES[fidx]
const rank: TR = RANKS[ridx]
return all[file + rank]
}
const select = function(key: string) : IRef {
return all[key]
}
const get = function(arg1: string | number, arg2: ?number) : IRef {
if(arguments.length === 1) {
return select (arg1)
}
if(arguments.length === 2) {
return compute (arg1, arg2)
}
}
const each = function (callback) {
Object.keys(all).forEach((key, idx) => {
callback.call(this, all[key], idx)
})
}
class Ref implements IRef {
constructor (refdef: TRefDef) {
this.file = refdef.file
this.fidx = refdef.fidx
this.rank = refdef.rank
this.ridx = refdef.ridx
this.key = this.file + this.rank
}
toString() : string {
return 'Ref: ' + '(' + this.fidx + ',' + this.ridx + ')' + ' ' + this.file + this.rank
}
move (df: number, dr: number) : Ref {
let f = FILES.indexOf(fidx)
let r = RANKS.indexOf(ridx)
f += df
r += dr
return all[FILES[f] + RANKS[r]]
}
}
FILES.forEach((file, fidx) => {
RANKS.forEach( (rank, ridx) => {
const key: string = file + rank
const ref: Ref = new Ref({ file, fidx, rank, ridx })
all[key] = ref
})
})
Ref.empty = new Ref('', -1, '', -1)
const Refs = { compute, select, each, get }
// let f = { compute, each, selection }
// console.log(f)
// export { compute, each, select, Ref }
export { Refs, Ref }

push added object to new array when calling getItems()

I am trying to display(log) the items that I added using the addItems() function when I call(log) the getItems() function..
console.log(cart.addItem("ITEMMSSS", 100, 10)) << puts out
ShoppingCart { itemName: 'ITEMMSSS', quantity: 100, price: 10 }
as expected
but the console.log(cart.getItems()) puts out -1-
when I console.log(this.addedItems) it logs out -undefined-(twice)
I don't understand why I don't have access to the returned value from the
addItem() function.
class ShoppingCart {
constructor(itemName, quantity, price) {
this.itemName = itemName
this.quantity = quantity
this.price = price
}
addItem(...items) {
const addedItems = new ShoppingCart(...items)
return addedItems
}
getItems(addedItems) {
const el = []
const selected = this.addedItems
const newArr = el.push(selected)
return newArr
}
clear(...item) {
// return items.slice(0, ...items).concat(items.slice(...items + 1))
}
clone(...items) {
// console.log(this)
// copiedCart.map((item) => {
// return item
// })
}
}
FIXed the issue,
class ShoppingCart {
constructor(items) {
this.items = []
}
addItem(name, quantity, pricePerUnit) {
const shopCart = this.items.push({
name: name,
quantity: quantity,
pricePerUnit: pricePerUnit
})
return shopCart
}
getItems(...items) {
const displayItems = this.items
return displayItems
}
clear(...items) {
const emptyCart = this.items.length = []
return emptyCart
}
clone(...items) {
const copyCart = new ShoppingCart()
copyCart.items = JSON.parse(JSON.stringify(this.items))
return copyCart
}
}
//
// const cart1 = new ShoppingCart('banana', 12, 23)
// const cart2 = cart1.clone()
// //
// console.log(cart2)
// //
module.exports = ShoppingCart;
But can't seem to get an immutable copy of the shoppingCart <--
fixed issue after reading about deep copying
clone(...items) {
const copyCart = new ShoppingCart()
copyCart.items = JSON.parse(JSON.stringify(this.items))
return copyCart
}
Couple ideas for author to think about:
1) addItem should be a function of an existing instance of ShopppingCart. Creating a new object inside addItems should not be necessary. I only know of returning a value from a setter to be usually only done for "fluent" setters practices so that you can chain them together. But that would be returning the current object.
2) getItems should usually not perform any logic. Usually getters return the current state of a variable / object member.
To address authors direct question:
You are returning the addItems object from the function but not storing it.
Try:
cart = cart.addItem("ITEMMSSS", 100, 10)

Categories