iiminov
iiminov

Reputation: 979

Knockout reference/value copy between arrays

Can anyone see what I am doing wrong here?

var card = function (item, groupMembers, removeCallback) {
    ...
    self.members = ko.observableArray(assignMembers(item.Members));
    ...
    function assignMembers(members) {
        var memberList = [];
        if (groupMembers !== "undefined" && groupMembers !== null) {
            //memberList = groupMembers.slice(0); // copy of group member list
            // control check to make sure we copied groupMembers correctly
            ko.utils.arrayForEach(groupMembers, function (member) {
                memberList.push(new member({ UserId: member.id, Name: member.name, Avatar: member.avatar }));
                console.log('Member: ', member.id, ' Checked: ', member.isChecked());
            });

            if (members !== "" && members !== null) {
                var memberIdList = members.split(',');
                ko.utils.arrayForEach(memberList, function (member) {
                    ko.utils.arrayForEach(memberIdList, function (memberId) {
                        if (member.id === parseInt(memberId, 10)) {
                            member.isChecked(true);
                            // print members that matched
                            console.log('Card: ', item.CardId, ' Member: ', member.id, ' Checked: ', member.isChecked());
                        }
                    });
                });
            }

            // control check to make sure things were assigned correctly
            ko.utils.arrayForEach(memberList, function (member) {
                console.log('Member: ', member.id, ' Checked: ', member.isChecked());
            });
            console.log(''); // spacer
            return memberList;
        }
        return memberList;
    }
    ...
}

For the most part I am trying to make a copy (value copy) of groupMembers array which was passed into this model. The reason for that is in the middle of the function. I am checking a comma separated list of references which were also passed into this model to mark members that were previously assigned to this card.

I've tried a few options

memberList = groupMembers;
memberList = groupMembers.slice(0);

all leading to what I believe is a reference copy. Meaning as I do changes to memberList array it actually changes groupMembers which is not good.

So if you imagine this is done for every card that gets instantiated. The result in the console window looks something like this:

// Card #1: initial memberList data
Member: 2 Checked: false
Member: 3 Checked: false
Member: 4 Checked: false
Member: 6 Checked: false

// Card #1: middle assignment
Card: 1004 Member: 3 Checked: true
Card: 1004 Member: 4 Checked: true

// Card #1: final memberList check
Member: 2 Checked: false
Member: 3 Checked: true
Member: 4 Checked: true
Member: 6 Checked: false

First card no probs.

// Card #2: initial memberList data
Member: 2 Checked: false
Member: 3 Checked: true
Member: 4 Checked: true
Member: 6 Checked: false

// Card #2: final memberList check
Member: 2 Checked: false
Member: 3 Checked: true
Member: 4 Checked: true
Member: 6 Checked: false

However second card demonstrates that code is working on the previous result.

// Card #3: initial memberList data
Member: 2 Checked: false
Member: 3 Checked: true
Member: 4 Checked: true
Member: 6 Checked: false

// Card #3: final memberList check
Member: 2 Checked: false
Member: 3 Checked: true
Member: 4 Checked: true
Member: 6 Checked: false

Third card same story.

// Card #4: initial memberList data
Member: 2 Checked: false
Member: 3 Checked: true
Member: 4 Checked: true
Member: 6 Checked: false

// Card #4: middle assignment
Card: 1002 Member: 2 Checked: true
Card: 1002 Member: 6 Checked: true

// Card #4: final memberList check
Member: 2 Checked: true
Member: 3 Checked: true
Member: 4 Checked: true
Member: 6 Checked: true

Fourth card no different but this time we had to check members with 2 and 6 references.

// Card #5: initial memberList data
Member: 2 Checked: true
Member: 3 Checked: true
Member: 4 Checked: true
Member: 6 Checked: true

// Card #5: middle assignment
Card: 1003 Member: 6 Checked: true

// Card #5: final memberList check
Member: 2 Checked: true
Member: 3 Checked: true
Member: 4 Checked: true
Member: 6 Checked: true

As you can see no the results I am after. Hence the value copy.

Despite my best efforts I run into a corner and I resorted to manually re-creating the array only to be greeted by:

TypeError: member is not a constructor
memberList.push(new member({UserId:member.id,Name:member.name,Avatar:member.avat...

error.

Can anyone see what I am doing wrong here?

update

Updated fiddler that I started working from.

You will notice that groupMembers are not actually being passed in correctly because my code looks different now and I am working on this to replicate the issue. Sorry about that.

update

I've been converting it a bit more. But it just keeps biting at my patience fiddler.

Upvotes: 0

Views: 90

Answers (1)

Ahuman
Ahuman

Reputation: 762

If your intention is just to deep copy the data, I would go with something like the below example

var jsonString = JSON.stringify(myModel);
var copiedData = JSON.parse(jsonString);

Upvotes: 1

Related Questions