I'm facing a peculiar issue that I can't quite wrap my head around.
In my Angular 1.4 project, I have a variable called $scope.videoModel
on the scope object, which serves as a model for capturing form data. When the form is submitted, the model is passed into a function like this:
ng-submit="createVideo(videoModel)
. In this function, various processing tasks, including regex operations like extracting a YouTube id, are performed.
While everything functions as expected, I've noticed that when I pass the scope object as an argument (as payload
) to a function, certain attributes that are updated in the argument also get updated on the $scope
.
For instance, if I pass $scope.videoModel.youtube
into createVideo
as payload
, and then extract the YouTube ID by assigning it like this:
payload.youtube = payload.youtube.match(regEx);
, the $scope.videoModel.youtube
property is also modified. This is evident by the form value changing from a full URL to just the ID.
It seems that passing in videoModel
as an argument to a function creates a reference to the variable rather than a copy. I haven't been able to find any information on this behavior. I'm considering creating a new variable like this: var tempVar = payload
, but it feels somewhat convoluted, and I'm unsure if I'm fundamentally wrong in my approach.
Does videoModel
get passed as a reference and not a copy?
Here's a condensed snippet of the code for clarity.
HTML:
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">YouTube Url</label>
<div class="col-sm-10">
<input class="form-control" ng-class="{ 'has-error' : newvideo.youtube.$invalid && newvideo.youtube.$touched, 'is-valid': newvideo.youtube.$valid }" placeholder="Youtube Url" ng-model="videoModel.youtube" name="youtube" ng-pattern="youtubeValidateRegex" required>
<div class="help-block" ng-messages="newvideo.youtube.$error" ng-show="newvideo.youtube.$touched">
<p ng-message="required">YouTube Url is required.</p>
<p ng-message="pattern">Please input a valid YouTube Url.</p>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10" ng-if="!success">
<button class="btn btn-default" ng-click="newVideo(videoModel)" ng-disabled="newvideo.$invalid"> Publish</button>
</div>
</div>
JS:
$scope.videoModel = {
youtube: 'https://www.youtube.com/watch?v=VkzVgiYUEIM',
vimeo: 'https://vimeo.com/193391290'
};
$scope.newVideo = function(payload) {
$scope.processing = true;
payload.user = $scope.user._id;
payload.filename = $scope.filename;
console.log(payload);
if(payload.type === 'vimeo') {
var matchVM = payload.vimeo.match($scope.vimeoExtractRegex);
console.log(matchVM);
if(matchVM) {
payload.vimeo = matchVM[5];
} else {
return toastr.error('Unable to extract Vimeo ID');
}
}
if(payload.type === 'youtube') {
var matchYT = payload.youtube.match($scope.youtubeExtractRegex);
if (matchYT && matchYT[1].length === 11) {
payload.youtube = matchYT[1];
} else {
return toastr.error('Unable to extract YouTube ID');
}
}
Videos.newVideo(payload)
.then(function(result) {
toastr.success('New video created.');
$scope.processing = false;
$scope.success = true;
$scope.result = result.data.result;
$scope.payload = result.data.payload;
})
.catch(function(response) {
$scope.error = true;
toastr.error(response.data.message, response.data.status);
});
return $scope.success;
};