Swappy
Swappy

Reputation: 160

Original model is changing when changing the copied data in SAPUI5

I am fetching some data (JSONArray) through an API and saving it in two models and an array variable. I am manipulating data in the array but it is changing the values in the models also. Below are my some code snippets :

 onInit : function(){
                this.addmodel = new sap.ui.model.json.JSONModel();
                this.addmodel.setDefaultBindingMode(sap.ui.model.BindingMode.OneWay);
                this.getView().setModel(this.addmodel, "Model");

                this.originalModel = new sap.ui.model.json.JSONModel();
                this.originalModel.setDefaultBindingMode(sap.ui.model.BindingMode.OneWay);
                this.getView().setModel(this.originalModel, "OrgModel");

                this.router.attachRoutePatternMatched(this._handleRouteMatched, this);
            },

Controller.js :

            _handleRouteMatched: function (evt) {
                if (evt.getParameter("name") !== "BookMeal") {
                    return;
                }

                $.ajax({
                    url: "/Non_sap_create_requests/odata/MealSelfLocMealType",
                    method: "GET",
                    dataType: "json",
                    success: function (data) {

                        that.mCopiedArray = $.extend([], data.value);
                        that.originalModel.setData(data);
                        that.addmodel.setData(data);

                    },
                    error: function (err) {

                    }
                });



            onFromDateSelect: function (oEvent) {

                if (Date.parse(fromDate) === Date.parse(currentDate)) {

                    var tempVal = that.mCopiedArray;
                    tempVal = formatter.mealContsraints(tempVal, currentDate, fromDate, currentTime, "null");
                    that.addmodel.setProperty("/value", tempVal);
                } else {
                    that.addmodel.setProperty("/value", that.originalModel.getProperty("/value"));
                }
            },

        });
    });

In the above code I am saving data in the array mCopiedArray and in 2 models - addmodel and originalModel. I am manipulating the data in formatter.js. Changing the data in mCopiedArray is also changing the data in addmodel and originalModel.

formatter.js :

        mealContsraints: function (value, currentDate, fromDate, currentTime, meal) {

            if (fromdate === currentdate) {
                while (ln--) {
                    if (value[ln].MealField === "Breakfast") {
                        value.splice(ln, 1);
                        break;
                    }
                }

                ln = value.length;

                if (currentTime > '11:30:00') {
                    while (ln--) {
                        if (value[ln].MealField === "Lunch") {
                            value.splice(ln, 1);
                            break;
                        }
                    }
                }

                ln = value.length;

                if (currentTime > '16:30:00') {
                    while (ln--) {
                        if (value[ln].MealField === "Eve Snacks") {
                            value.splice(ln, 1);
                            break;
                        }
                    }
                }

                if (currentTime > '18:00:00') {
                    while (ln--) {
                        if (value[ln].MealField === "Dinner") {
                            value.splice(ln, 1);
                            break;
                        }
                    }
                }

            }

Upvotes: 2

Views: 2302

Answers (3)

Geraldo Megale
Geraldo Megale

Reputation: 363

One way to make a deep copy of an object is to serialize it to json and the deserialize it to a new object:

Let objString = JSON.stringfy(obj): Let newObject = JSON.parse(objString)

PS: that will work for serializable properties and if you have A huge object you might run into performance issues.

Upvotes: 0

Marc
Marc

Reputation: 6190

$.extend([], data.value); does not create a deep copy. So if you modify an item in your array (e.g. change MealField from Dinner to Midnight Snack) it will also be changed in the model.

But if you modify the array itself (e.g. remove an item from the array) that should not affect the model.

I did a small snippet for this:

const mData = {value: [
    { MealField: "Dinner", id: 3 },
    { MealField: "Lunch", id: 2 },
    { MealField: "Breakfast", id: 1 }
]};

const oModel = new sap.ui.model.json.JSONModel(mData);
const aCopy = $.extend([], mData.value);
aCopy.splice(1, 1);
// arrays should be different
console.log(aCopy);
console.log(oModel.getProperty("/value"));
aCopy[0].MealField = "Midnight Snack";
// single item should be the same
console.log(aCopy[0]);
console.log(oModel.getProperty("/value/0"));

So the problem shouldn't be the formatter but something else?

Btw your formatter isn't a formatter. A real formatter should return a value and not have side effects (like modifing models/data).

Upvotes: 1

umit
umit

Reputation: 57

The objects are working reference logic so you can use jquery.extend().enter image description here

Upvotes: 0

Related Questions