Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

change:attribute not firing

I do this: on('change:attribute:current', function(obj) {     log('Character changed: ' + obj.get('name')); }); And when I do this: var attr = findObjs({ type: 'attribute', characterid: character.id, name: 'myAttribute' })[0]; if (!attr) { attr = createObj('attribute', { name: 'myAttribute', current: false, characterid: character.id }); } attr.set('current', !attr.get('current')); Nothing happens. I verified that the attribute is changed on the character. I also tried using the 'change:attribute' event but that didn't do anything either. What am I doing wrong?
1544924019
GiGs
Pro
Sheet Author
API Scripter
what is this line intended to do? attr.set('current', !attr.get('current')); Can you post the full code you are using?
1544926814
GiGs
Pro
Sheet Author
API Scripter
I've done some testing, and the problem seems to be this line:  current: false, If you change it to  current: 'false', you get better behaviour. It fails the first time, but works after that/ If you instead set it to  current: 'false', It works first time. So this looks like something to do with interpretation of truthy and falsy values. You can bypass the issue by swapping this: attr.set('current', !attr.get('current')); to attr.set('current', attr.get('current') ? false : true); With this approach, keep this line unchanged: current: false, I'm not entirely sure why you want this toggle, but the above should fix it.
1544934089
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
There are two issues at play here. The API is deliberately prevented from triggering itself except in the case of chat messages. This is to prevent the creation of infinite loops that would evade the infinite loops detection. Additionally, the API is completely event driven, so your second snippet of code needs to listen for something (a chat message, a change of some object) in order to trigger. This is part of what GiGs was probably looking for when he asked for the complete code.
A clarification on Scott's point 2):   Code that isn't part of an event handler will run immediately, which will have unexpected effects.  For example, any attempts to access character attributes will fail.   Wrap your test code in on('ready', () => {   code here ...  }); so that it will run when everything is actually loaded and ready to operate. Regarding your attempt at using a boolean attribute, I don't think those work.  Attributes to represent truth values are usually implemented as numbers with 0 for false, and non-zero for true.  You can see this if you look at some of the existing attributes that represent flags.  I believe string and number are the only supported types.   So a toggle would look like  attr.set('current', (attr.get('current') > 0) ? 0 : 1);
1544995157
GiGs
Pro
Sheet Author
API Scripter
I tested this, and it worked fine attr.set('current', attr.get('current') ? false : true); As long as the attribute was set like so current: false, and not current: 'false', That doesnt seem to be a very stable approach though since there's clearly some inconsistency in how roll20 handles booleans and strings-as-booleans, so Ammo is almost certainly right that it is better to use numbers.
1544995823
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
GiGs, I would check how that stays stable through game loads.
1544996165
GiGs
Pro
Sheet Author
API Scripter
*nods* I did acknowledge it might not be a stable approach long-term. 
Thanks for the info. What I was doing with  attr.set('current', !attr.get('current')); is to guarantee the attribute changed. It is purely for testing. The code that triggered the attribute change was in a chat event listener (for a specific message) and I always made sure the API was ready before triggering the event.  I didn't expect boolean values to not work since I see many properties with string and numeric values. I can easily switch to numeric or string.
Mike said: Thanks for the info. What I was doing with  attr.set('current', !attr.get('current')); is to guarantee the attribute changed. It is purely for testing. The code that triggered the attribute change was in a chat event listener (for a specific message) and I always made sure the API was ready before triggering the event.  I didn't expect boolean values to not work since I see many properties with string and numeric values. I can easily switch to numeric or string. You're not wrong... there is very little error checking in the API.  Think of it as more of an exposed internal API that works for all those cases where it works.   If this was a widely distributed thing, it should probably error out on values that aren't going to work correctly.   But this is more like extending some internal code to a small community of scripters, unfortunately without open source :). So go ridiculously slowly when you try something new.  The other day I started reading GM Notes from tokens in addition to journal entries, and found that they were URL encoded for some reason.  Nope, not just HTML escaped, but HTML that was then URL escaped.   Just for tokens though, which store their notes with the same DB record (apparently), while journal entries use a separate blob that you have to read through a callback.   *shrug*     I believe there is no unit testing on the API other than what The Aaron did. Ok that was enough rant for today (I promise?)