简体   繁体   中英

How to create a new Object instead of mutating it - javascript?

Here i am having a Object ie ApiData1 . Where it has color key value pair inside properties . I am changing the color values according to ApiData2 value numberOfProjects , and having a range where numberOfProjects values lies between a set of range i am updating the color value. It is working fine. But after updating, I am setting this value in a state [React]. However on initial load color has updated and working fine. After a button click i am doing exactly this process with Different ApiData2 value. ApiData1 color value gets updated. But react doesn't detect the change.

I suspect because of mutating the ApiData1 . Its not picking the prop change.Instead of mutating is there any way to create a new ApiData1 value with it. Anyway to recreate this logic.

Your help or suggestion is much appreciated.

Thanks in advance.

Here is the WORKING DEMO LINK


let ApiData1 = {
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "geometry": {
                "type": "MultiPolygon"
            },
            "properties": {
                "color": 1,
                "id": 10,
                "stateId": 10,
                "name": "Tamil Nadu",
                "code": "TN"
            }
        },
        {
            "type": "Feature",
            "geometry": {
                "type": "MultiPolygon"
            },
            "properties": {
                "color": 1,
                "id": 11,
                "stateId": 11,
                "name": "Karnataka",
                "code": "KA"
            }
        },
        {
            "type": "Feature",
            "geometry": {
                "type": "MultiPolygon"
            },
            "properties": {
                "color": 1,
                "id": 12,
                "stateId": 12,
                "name": "Pondicherry",
                "code": "PY"
            }
        }
    ]
}

let ApiData2 = [
    {
        id: 10,
        name: "Tamil Nadu",
        code: "TN",
        latitude: 29.9964948,
        longitude: 81.6855882,
        latestMetric: {
            stateId: 10,
            year: 0,
            numberOfProjects: 1433,
        }
    },
    {
        id: 11,
        name: "Karnataka",
        code: "KA",
        latitude: 21.9964948,
        longitude: 82.6855882,
        latestMetric: {
            stateId: 11,
            year: 0,
            numberOfProjects: 3500,
        }
    },
    {
        id: 12,
        name: "Pondicherry",
        code: "PY",
        latitude: 22.9964948,
        longitude: 87.6855882,
        latestMetric: {
            stateId: 12,
            year: 0,
            numberOfProjects: 5500,
        }
    }
];

function updateColor() {
    function updateColorValue(colorJsonObject, colorValue) {
        let updatedProperties = {
            ...colorJsonObject.properties,
            color: colorValue
        };
        colorJsonObject.properties = updatedProperties;
        return { ...colorJsonObject };
    }

    let range = [
        {
            "Minimum": 1,
            "Maximum": 2000,
            "color": 1
        },
        {
            "Minimum": 2000,
            "Maximum": 4000,
            "color": 2
        },
        {
            "Minimum": 4000,
            "Maximum": 6000,
            "color": 3
        }
    ]

    ApiData1.features.map(colorObject =>
        ApiData2.map(apiData => {
            if (
                colorObject.properties.stateId === apiData.latestMetric.stateId
            ) {
                range.map(i => {
                    if (
                        apiData.latestMetric.numberOfProjects >= i.Minimum &&
                        apiData.latestMetric.numberOfProjects <= i.Maximum
                    ) {
                        updateColorValue(colorObject, i.color);
                    }
                });
            }
        })
    );
    return ApiData1;
}

let colorValue = updateColor();

console.log(colorValue);

I have done something like this to create a newObject, instead of mutating it,

  
     function updateProperties(colorJsonObject, colorValue) {
        let updatedProperties = {
            ...colorJsonObject.properties,
            color: colorValue
        };
        console.log(updatedProperties)
        return updatedProperties;
        
    }
    let newData = {...ApiData1}

    newData.features.map(colorObject =>
        ApiData2.map(apiData => {
            if (
                colorObject.properties.stateId === apiData.latestMetric.stateId
            ) {
                range.map(i => {
                    if (
                        apiData.latestMetric.numberOfProjects >= i.Minimum &&
                        apiData.latestMetric.numberOfProjects <= i.Maximum
                    ) {
                    
                            let value = updateProperties(colorObject, i.color)
                        return {...colorObject,properties:value}
                    }
                });
            }
        })
    );
    return newData;
}

let colorValue = updateColor();

console.log(colorValue);

value has been updating it on the updateProperties function, but it is not reflected in the newData object. still i am getting oldObject, not the new one.

HERE IS THE LINK FOR THAT

You aren't using the result of newData.map . Also you don't need a nested map since all you want to operate on is a specific object.

What you need is to find that object and update it. Make use of Array.prototype.find to find the relevant matching object for state and then update it using the range array by looping over it

 let ApiData1 = { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "MultiPolygon" }, "properties": { "color": 1, "id": 10, "stateId": 10, "name": "Tamil Nadu", "code": "TN" } }, { "type": "Feature", "geometry": { "type": "MultiPolygon" }, "properties": { "color": 1, "id": 11, "stateId": 11, "name": "Karnataka", "code": "KA" } }, { "type": "Feature", "geometry": { "type": "MultiPolygon" }, "properties": { "color": 1, "id": 12, "stateId": 12, "name": "Pondicherry", "code": "PY" } } ] } let ApiData2 = [ { id: 10, name: "Tamil Nadu", code: "TN", latitude: 29.9964948, longitude: 81.6855882, latestMetric: { stateId: 10, year: 0, numberOfProjects: 1433, } }, { id: 11, name: "Karnataka", code: "KA", latitude: 21.9964948, longitude: 82.6855882, latestMetric: { stateId: 11, year: 0, numberOfProjects: 3500, } }, { id: 12, name: "Pondicherry", code: "PY", latitude: 22.9964948, longitude: 87.6855882, latestMetric: { stateId: 12, year: 0, numberOfProjects: 5500, } } ]; function updateColor() { function updateColorValue(colorJsonObject, colorValue) { let updatedProperties = {...colorJsonObject.properties, color: colorValue }; colorJsonObject.properties = updatedProperties; return {...colorJsonObject }; } function updateProperties(colorJsonObject, colorValue) { let updatedProperties = {...colorJsonObject.properties, color: colorValue }; console.log(updatedProperties) return updatedProperties; } let range = [ { "Minimum": 1, "Maximum": 2000, "color": 1 }, { "Minimum": 2000, "Maximum": 4000, "color": 2 }, { "Minimum": 4000, "Maximum": 6000, "color": 3 } ] let newData = {...ApiData1, features: ApiData1.features.map(colorObject => { const apiData = ApiData2.find(apiData => { if ( colorObject.properties.stateId === apiData.latestMetric.stateId ) { return true; } return false; }); let newValue; range.forEach(i => { if ( apiData.latestMetric.numberOfProjects >= i.Minimum && apiData.latestMetric.numberOfProjects <= i.Maximum ) { let value = updateProperties(colorObject, i.color) newValue = {...colorObject,properties:value} } }); return newValue; }) } return newData; } let colorValue = updateColor(); console.log(colorValue);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM