Newtt
Newtt

Reputation: 6200

Scope variable is also updating non scope variable on change

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.

Upvotes: 0

Views: 125

Answers (2)

EsseTi
EsseTi

Reputation: 4301

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/

Upvotes: 1

Peter Fischaleck
Peter Fischaleck

Reputation: 342

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!

Upvotes: 0

Related Questions