1

My Vue.js version is v1.0.28. I was wondering how I could use Vue.$set to set a deep property of an object array. For example, I have:

this.pairs = [
    {
        "left_media": {
            "name": "A",
            "show": false
        },
        "right_media": {
            "name": "B",
            "show": false
        }
    },
    {
        "left_media": {
            "name": "B",
            "show": false
        },
        "right_media": {
            "name": "A",
            "show": false
        }
    }
]

I need to loop through this.pairs array and update the show property of each media name == A to true.

I can seem to update them easily via a for loop, but the view won't change. I've done some research and seems like Vue.$set can help fix this, but I can't seem to get it work in this case.

How do I use $set to do: this.pairs[i].left_media.show = false;?

EDIT

AJAX call to update show_comment

toggleComment: function(media, which_media) {
  this.$http.post('/api/project-media/update.json', {
    id: media.id,
    show_comment: !media.show_comment
  })
  .then(function (response) {
    if (response.body.success) {
      // update show_comment status for this media in all pairs\
      for (let pair of this.pairs) {
        for (let key of Object.keys(pair)) {
          if (key == 'project_media_left' || key == 'project_media_right') {
            if (pair[key].id == media.id) {
              this.$set(pair[key], 'show_comment', !media.show_comment);
            }
          }
        }
      }
    }
  }, function (response) {
  });
}
5
  • How are you adding items to pairs? Commented Jun 2, 2017 at 4:58
  • Ah, the array is pulled from the DB :) Commented Jun 2, 2017 at 5:17
  • So, how specifically is the data from the database added to pairs? Commented Jun 2, 2017 at 5:18
  • Data from the sever side has been formatted and passed down to the client side, I brought it over using PHP json_encode i.e. var pairs = <?= json_encode($pairs, JSON_NUMERIC_CHECK); ?>; Commented Jun 2, 2017 at 5:22
  • Do any of the options in the answer work for you? If not I guess we need to see more code. Commented Jun 2, 2017 at 5:25

1 Answer 1

1

If your target environment supports Object.values or you are using babel or something to compile, then its just

for (let pair of this.pairs)
  for (let v of Object.values(pair))
    if ('A' == v.name) v.show = true

If not then

for (let pair of this.pairs)
  for (let key of Object.keys(pair))
    if (pair[key].name == 'A')
      this.$set(pair[key], 'show', true)

Example.

But to be honest,

for (let pair of this.pairs)
  for (let key of Object.keys(pair))
    if (pair[key].name == prop)
      pair[key].show = true

also works for me, so I wonder if there is something else going on with your issue.

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

8 Comments

I've tried your solutions. A couple of issues though: The method using $set reports an error Uncaught (in promise) TypeError: t.trim is not a function(…). Perhaps it's not setting the right property? The other methods do successfully change the value of the media, but the change is not showing on the browser.
@nogias Can you post the code where you are doing the update? Sounds like it is in an Ajax callback.
You are right, there's an AJAX call. I've updated the question above, sorry it's a bit different from my simplified example above but the idea is the same.
@nogias Where is this different from yours? This appears to work. codepen.io/Kradek/pen/YQKjMB?editors=1010
Just checked, yeah no difference, although using $set always throws me an error t.trim is not a function.... It's getting strange.
|

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.