1

I get some data via an API call

 getPosts(postRequest: PostRequest): void {    
    this._postService.getPosts(postRequest).subscribe(result => {    
      const postList = result as PostList
      this.posts = postList.posts    
    });    
  }

the this.posts, contain an array of post objects. That in this case look like this:

{
    id: 123
    rating: {
      datetime: 1496782640,
      down:0,
      hot:8061.5151856,
      id:344,
      up:2
    }
}

Later I want to change the item

  incrementVote(post: Post) {
      post.rating.up++;        
  }

ERROR:

main-browser.min.js:2 ERROR TypeError: Cannot assign to read only property 'up' of object '[object Object]'
    at PostListComponent.incrementVote (main-browser.min.js:34)
    at PostListComponent.vote (main-browser.min.js:34)
    at Object.handleEvent (main-browser.min.js:54)
    at Object.handleEvent (main-browser.min.js:6)
    at Object.handleEvent (main-browser.min.js:7)
    at dispatchEvent (main-browser.min.js:5)
    at main-browser.min.js:5
    at HTMLButtonElement.<anonymous> (main-browser.min.js:21)
    at ZoneDelegate.invokeTask (main-browser.min.js:67)
    at Object.onInvokeTask (main-browser.min.js:3)

Why is the this.posts object read-only?

This suddenly happen seemingly without any changes to the code. I also have the same problem in another project, and then it works if I compile with --aot and not when I compile in dev mode.

How can I fix this? I need to be able to change values from the API. Why does this happen?

PS. The object is also used in the HTML, like so:

 <div class="row" *ngFor="let post of posts; let postIndex = index">
      <div class="col-md-12">

        <app-post [post]="post" [fontSize]="30"></app-post>

2 Answers 2

1

Ok, try not incrementing but assigning. Such as:

incrementVote(post: Post) {
      let newVal = post.rating.up + 1;
      post.rating.up = newVal;        
  }

Maybe the post object has been created with one of these:

Meaning that has been created as a read-only.

Here I found out that replacing the value with another object works. I'm not sure though if it can be applied in your case.

UPDATE:

Another solution would be to actually force the property to be writable, example:

up: {
    value: 2,
    writable: true
},
Sign up to request clarification or add additional context in comments.

3 Comments

Still having the same problem, haven't tried adding 'writable', but cannot do that do every object..
@ganjan thinking abiut it, you could create a class PostClass that has X properties with writable. And then you just instance it, this way you won't have to do that 1000 times, just once. No?
tried setting writable too, didn't make any difference.
0

Think I found the reason for the readonly property. Seems it is because of the ngrx/store library. As soon as I use

    this._store.dispatch({
           type: EVENT_X,
           payload: new EventPayload({
             variable: Something
           })
     });

The variable "Something" becomes readonly. This makes sense since it is not meant to be changed directly with ngrx/store.

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.