javascriptvue.jsrethinkdbhorizon

Incrementing value in a Horizon collection


I am trying to figure out how to perform the basic task of incrementing a value in horizon.io collection. For instance, I have an <h1> tag that could represent an upvotes button, and I want the upvotes count to be persistent.

<h1 @click="inc">{{foo}}</h1> <!-- foo is local variable -->
    <ul>
      <li v-for="message in me">
      {{message.value}} <!-- message.value is upvote value from collection --> 
      </li>
   </ul>

Then in the Vue instance:

created() {
  me.store({
    datetime: new Date(),
    value: this.foo // local data variable set to 0 initially. 
  }).subscribe(
      result => console.log(result),

      error => console.log(error)
    )
 var self = this
 me.watch().subscribe(function(data){
      data.map(function(data){
        self.foo = data.value
      })
  })  
},

Then I am trying to update the value each time the <h1> tag is clicked:

inc(){
  me.update({
    id: 1,
    value: this.foo++
  })
}

How do I update a value in the collection, and do I have to render the collection in my template in order to have access to the value in the collection?


Solution

  • First off, you can avoid the var self = this headache by just using the new arrow function syntax. this even within functions of functions will still use the outermost this:

    created() {
      me.store({
        datetime: new Date(),
        value: this.foo // local data variable set to 0 initially. 
      }).subscribe(
        result => console.log(result),
        error => console.log(error)
      );
      me.watch().subscribe((data) => {
        data.map((data) => {
          this.foo = data.value;
        })
      })  
    },
    

    Your increment .update function looks correct but I'd do this instead:

    inc(){
      this.foo++;
      me.update({
        id: 1,
        value: this.foo
      });
    }
    

    Post-fix and pre-fix can get tricky, and I'm not sure if it would result in the output you'd expect since it would return the value of this.foo and then increment.

    How do I update a value in the collection, and do I have to render the collection in my template in order to have access to the value in the collection?

    If I'm understanding the question correctly, you're using .update correctly so you know how already! But from my experience in Vue, you do not have to render the collection to have access to the value? this.foo is being reassigned every time the document with id: 1 changes. But if you don't supply an id when you initially .store an object, we will provide one for the document. So your initial .store code should probably look like this: try { me.insert({ id: 1, datetime: new Date(), value: this.foo // local data variable set to 0 initially. }).subscribe( result => console.log(result), error => console.log(error) ); } catch(e) { console.log("Already exists!", e); }

    Also you only want to subscribe to changes to that one id: 1 document:

    me.find(1).watch().subscribe((data) => { data.map((data) => { this.foo = data.value; }); });

    Does that answer your question?

    EDIT: Forgot, to change .watch

    EDIT2: Changing .store (which overwrites the data every single time) to .insert which will insert if the document doesn't exist and error if it does. We want this functionality because we just want to insert if it doesn't exist and do nothing if it does, versus overwriting the value field.