TypeError: Attempted to assign to readonly propert

2020-06-01 05:15发布

问题:

Our Mobile App is getting "TypeError: Attempted to assign to readonly property." only on IOS 8 and the stack traces are not helpful and seem to be in Angular code.

This might be happening because of the "use strict" on top level of Angularjs code. My questions are (1) why did it start happening only on IOS8? is this an IOS8 bug? (2) or is this an angular bug surfaced on IOS8? (3) Or maybe we are violating strict mode rules but only IOS8 started to catch them! I am skeptical about the third option because strict mode is supported by other major browsers.

I have found one similar reported issue here.

回答1:

Looks like this is an IOS8 bug

At least the guys at ember.js will temporarily strip the 'use strict' from their code until it's fixed. Ember.js issue



回答2:

SOLUTION - Note:

  1. angular.copy didn't work for me
  2. lodash cloneDeep didn't work either.
  3. removing "use strict"; didn't help - It just removed the error being logged in a try/catch arround the "erroneous" assignment to a readonly value

For us, the value that was being passed back from the SQL promise value was an array of objects.

The values that we were getting "read only" error on were strings, bools, and numbers.

console.log('this will log');
sqlReturnArray[0].name = "Bob"; // read only error here
console.log('wouldnt get to here to log');

I figured, well, if I can't assign values to properties on THOSE objects within the array, why can't I just copy over all the objects' values? Assignment of objects is by reference so just doing a loop over the array won't help. You need to loop over the keys and values.

This solved our problem

// where sqlReturnArray is the object given from the SQL promise
var newArrayOfObjects = [];
angular.forEach(sqlReturnArray, function (obj) {
  var newObj = {};
  angular.forEach(obj, function (val, key) {
    newObj[key] = val;
  });
  newArrayOfObjects.push(newObj);
});


回答3:

I just had this error and the fix was pretty simple.

My Code was-

    $http.get('/api/v1/somedata').then(function(result){
        $scope.data.somedata = result.data.list;
    });

I get the TypeError in the assign. Because I haven't defined $scope.data.somedata anywhere and it got $scope.data undefined and trying to assign some property to it initiated the error.

I simply put $scope.data = {somedata : [] } in the top of the controller. I can also get rid of this error by changing $scope.data.somedata to $scope.somedata because any property of the $scope object that is undefined will end up to the $rootscope and won't give any error. I found this is pretty hard to debug my view-model. And also for this TypeError I can find out what exactly is wrong.



回答4:

I had it with a form. my issue was because of binding an SQL Return Object to an input. after coping with angular.copy() problem resolved.

try to copy your return values and retry.

$scope.yourFunc= function(result) {
        var item = angular.copy(result.rows.item(0));
        ...
    };