0

I'm writing a user settings page in Angular that will be used to update the users profile settings. This is how I've done it (pardon my use of jquery please)

$scope.userObj = {};
var userObjTemp = {};
$http.get('/api/to/get/user').success(function(data) {
    if (data.success != true) {
        $state.go('index');
    } else {
        $scope.userObj.user = data.response; //scope variable to show in html form
        userObjTemp.user = data.response; //temp data in case someone cancels editing
        var tempDob = $scope.userObj.user.dob;
        $scope.userObj.user.dob = tempDob.split('-')[2] + '/' + tempDob.split('-')[1] + '/' + tempDob.split('-')[0];
        console.log({
            userObjData: $scope.userObj
        });
        console.log({
            tempData: userObjTemp
        });
    }
});
$scope.showSetting = function(target) {
    $('.setting-edit-row').hide();
    $('.jr-input-setting').show();
    $('#' + target + '-input').hide();
    $('#' + target).show();
}
$scope.saveSetting = function(key) {
    var postDict = {};
    postDict[key] = $scope.userObj.user[key];
    $http.put('/api/user', postDict).success(function(data) {
        $scope.userObj.user = data.response;
        $('.setting-edit-row').hide();
        $('.jr-input-setting').show();
    })
}
$scope.shutSetting = function(target) {
    $scope.userObj.user = {};
    $scope.userObj.user = userObjTemp.user;
    $('#' + target).hide();
    $('#' + target + '-input').show();
}

My HTML is as follows:

<div class="row setting-fixed-row">
    <div class="col-lg-2">
        <div class="setting-label">
            Name
        </div>
    </div>
    <div class="col-lg-8">
        <input class="jr-input-setting" id="setting-name-input" disabled="true" ng-model="userObj.user.display_name" type="text" placeholder="Display Name">
    </div>
    <div class="col-lg-2">
        <div class="edit-btn" ng-click="showSetting('setting-name')">
            Edit
        </div>
    </div>
    <div class="col-lg-12 setting-edit-row" id="setting-name">
        <div class="row">
            <div class="col-lg-12">
                <span class="glyphicon glyphicon-remove shut-det" style="margin-bottom: 5px;" ng-click="shutSetting('setting-name')"></span>
            </div>
            <div class="col-lg-offset-2 col-lg-8">
                <input class="jr-input-edit" ng-model="userObj.user.display_name" placeholder="Display Name" id="display_name" ng-change="showVal()">
            </div>
            <div class="col-lg-2">
                <div class="save-settings" ng-click="saveSetting('display_name')">
                    Save
                </div>
            </div>
        </div>
    </div>
</div>

The idea behind shutSetting() is to shut the editing panel setting-edit-row and restore the original data that I got from the api. However, when I do this, it shows me the temp variable being the same as the $scope.userObj variable. I added a $scope.showVal function to show the variables on change of the input form:

$scope.showVal = function(){
    console.log({userObj: $scope.userObj});
    console.log({temp: userObjTemp});
}

For some reason, both variables are getting updated. How do I fix this as I've never faced something similar before.

5
  • well you assign to that variable userObjTemp.user = data.response; //temp data in case someone cancels editing so its there? Commented May 7, 2015 at 10:10
  • try with userObjTemp.user = angular.copy(data.response) Commented May 7, 2015 at 10:11
  • So the idea is to keep two copies of the data response. One that remains constance regardless of editing and one that is used for editing. Shouldn't userObjTemp not be equal to userObj on change of userObj? Commented May 7, 2015 at 10:12
  • @EsseTi, that worked. You can add that as an answer below. How exactly does this help though? Commented May 7, 2015 at 10:16
  • they are referenced not copied. so if you update the userObj also the userObjTemp is also updated. thus, use the copy instead of plain assigment Commented May 7, 2015 at 10:16

2 Answers 2

1

The problem is that you are referencing objects instead of copying them. Thus

$scope.userObj.user = data.response;
userObjTemp.user = data.response; 

points all to the same object. Then, when you update one of the two also the other gets updated.

userObjTemp.user = angular.copy(data.response)

this makes a copy.

Just in case: https://jsfiddle.net/qzj0w2Lb/

Sign up to request clarification or add additional context in comments.

Comments

0

The problem is, that both of your variables are referencing the same object data.response. Depending on the object, you could use $.extend(true, {}, data.response); to get a clone of the object.

Be aware though, that this is not a true "deep copy" when custom objects are involved!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.