Home > Back-end >  Cannot set properties of undefined when using eval but works without eval
Cannot set properties of undefined when using eval but works without eval

Time:09-08

I am trying to use eval() to dynamically update a variable that I have to access by path like myArray[0][0][1][0]... But for some reason it is giving me this error:

Uncaught TypeError: Cannot set properties of undefined (setting '$folded')

If I do it without eval like this productCategoriesTree[1].$folded = false - then it works.

I am using Vue 3 so perhaps it might be related to Vue somehow.

addNewProductCategory() function is the problem:

// useProductCategoriesTree.ts
import { v4 as uuidv4 } from 'uuid'
import TreeItem from '@/types/TreeItem'
import { try as tryCatch } from 'radash'
import { getCurrentInstance } from 'vue'
import { ProductCategory, ProductCategoryTreeInput } from '@/types/graphql/graphql'
import productCategoryApi, { FRAGMENT_PRODUCT_CATEGORY_TREE } from '@/api/productCategoryApi'

export function useProductCategoriesTree() {
    let productCategoriesTree = $ref<TreeItem<ProductCategory>[]>([])

    const { emit } = getCurrentInstance() as any

    const getProductCategoriesTree = async () => {
        const [error, productCategories] = await tryCatch(productCategoryApi.getProductCategoryList)(FRAGMENT_PRODUCT_CATEGORY_TREE)

        productCategoriesTree = buildProductCategoriesTree(productCategories)
    }

    const buildProductCategoriesTree = (productCategories: ProductCategory[]): TreeItem<ProductCategory>[] => {
        return productCategories.map(productCategory => ({
            data: productCategory,
            children: (productCategory.children && productCategory.children.length)
                ? buildProductCategoriesTree(productCategory.children)
                : undefined
        }))
    }

    const selectProductCategory = (productCategoryUuid: string) => {
        emit('select', productCategoryUuid)
    }

    // treePath could be [0, 1, 0, 0, 1] - it is dynamic
    const addNewProductCategory = (parentCategoryUuid: string, treePath: number[]) => {
        const newProductCategory = {
            uuid: `__NEW-${uuidv4()}`,
            namePlural: 'new',
            parent: { uuid: parentCategoryUuid }
        }

        if (!productCategoriesTree[1].children) {
            productCategoriesTree[1].children = []
        }

        productCategoriesTree[1].children?.push({
            data: newProductCategory as ProductCategory,
            children: [],
        })

        console.log(`productCategoriesTree[${treePath.join('][')}].$folded = false`)
        // productCategoriesTree[1].$folded = false

        // this works
        productCategoriesTree[1].$folded = false

        // this does not work
        eval(`productCategoriesTree[${treePath.join('][')}].$folded = false`)
    }

    getProductCategoriesTree()
    
    return $$({
        productCategoriesTree,
        selectProductCategory,
        addNewProductCategory,
    })
}

CodePudding user response:

I'd try any other approach that didn't use eval. For example:

let thingToUpdate = productCategoriesTree;

treePath.forEach(el => thingToUpdate = thingToUpdate[el]);

thingToUpdate.$folded = false;

Similar to this question: Javascript: Get deep value from object by passing path to it as string

  • Related