5

I'm learning how to use ractive and can't solve a problem, the code is at the following jsfiddle.

The gist of what I'm doing is counters for a queue (last object in array is current person): 1. A counter to display the queue number of the current person 2. A counter to display the size of the queue

A) works correctly but it is bloated with logic so I tried to convert it into a separate variable, as shown in B) but it doesn't update at all.

I put an observer in the code to watch when there is any change to the queue variable. I expect it to show an alert every time I click on "skip current person" or "delete current person" but the alert only shows up in the first time I load the page.

    ractive.observe({
      'queue.0.queueNo': alert('here')
    });
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
trashbear
  • 109
  • 5
  • You're not changing their queueNo - the data is staying the same, with the whole object being moved from front to back – MDEV Sep 19 '13 at 11:25
  • I should have made my variables more obvious, queueNo is the attribute of the element. I was referring to queueNum, that is a key defined in the data hash of the ractive object. – trashbear Sep 20 '13 at 15:41

2 Answers2

6

Wim's answer is a good one - {{num(queue)}} is an elegant solution.

The reason you can't use queueNum is that when you do

queueNum = people[(people.length-1)].queueNo

the value of queueNum is set to whatever the value of people[(people.length-1)].queueNo is at the time of the statement. When the queue is altered, queueNum doesn't get re-evaluated. This isn't a Ractive thing so much as a JavaScript thing.

Another way of saying it is

a = 1;
b = 2;
foo = a + b; // foo === 3

a = 3;
b = 4;
alert( foo ); // alerts '3' - foo is the same, even though a and b changed

This is actually the same reason that the alert('here') was only triggering when the page loaded - rather than telling Ractive to trigger the alert when the value changed by wrapping it in a function, as in the second code block of Wim's answer, the code was executed immediately.

Rich Harris
  • 28,091
  • 3
  • 84
  • 99
  • Thanks for the reply Rich, that made things very clear. I'm new to programming in general so the javascript explanation was helpful. – trashbear Sep 28 '13 at 00:49
3

you can make queueNum a function based on queue like this:

num: function(q) { return q[(q.length-1)].queueNo;}

and call it like so: {{num(queue)}} now when queue or people gets updated reactive knows it has to update num to. You don't even have to call ractive.update(). For the observe also make it a function and it will work:

ractive.observe({
    'queue.0.queueNo': function(a,b) { alert('here');}
});
Wim
  • 1,967
  • 11
  • 19
  • Thanks it works now! Do you know why I couldn't use my queueNum as I had in my example (set to read from the people array)? I'm just curios as queue updated correctly so I expected the same behavior from queueNum. – trashbear Sep 20 '13 at 15:49
  • Don't know the exact inner workings of ractive, so don't know why it doesn't work. Just my own experience with ractive that it works like this. – Wim Sep 24 '13 at 11:46