1

I have an object Foo that has 2 public properties: A and B.

These properties can be changed from outside, as the application I'm working on is using a data-binding architecture. This is the front-end (client) code, but it's also communicating with a server to fetch data.

So my object is listening for changes to both A and B.

Any change in A or B is triggering the update() method, which triggers a request to the server.

I also have a piece of logic in my object Foo that says every time you change B, you have to reset A to its initial value.

My problem is, how do I deal with updating B without triggering the update() method twice?

enter image description here

Looking at the image above, the green path should always trigger an update. The red path ends up sometimes triggering 2 updates, because by changing B it changes A (if it's not the initial value), which always triggers an update.

I have to add that everything is asynchronous so the observers for my properties don't notify me immediately after changing objects. (design choice of the platform and language I'm working in – Polymer.JS). So this makes it harder to set a flag before changing B from A - I tried this but it didn't work, as the watcher method gets triggered after the chain of changes has executed.

As I come from the front-end world, with a background in graphic design, I don't have the knowledge necessary to spot the mistakes I might be doing, but I want to learn, so I'd like you to point me to reference material and/or books I can read about the correct applications of the observer pattern.

Is there a pattern that deals with this particular scenario and what are possible solutions to this?

If the observer pattern isn't the right choice for this, is there another pattern I could use internally that allows me to expose only the two properties A and B to the outside world?

A third option would be that I'm applying the right pattern, but the platform doesn't support what I'm trying to achieve. I'd like to know this so I can post the question on StackOverflow under the right tags.

2

You make a special message to A that changes it in a way that is not propagated. Its a common idiom where you want general updates to send notifications, but not internal updates or refreshes.

For example, I have a dialog that has notification handlers for changes to various controls, but in the initialisation I want to set the controls initial state - without sending these notifications. In this case, I simply set an 'initialising' flag that the notification handler checks for, if its set the handler simply does nothing.

If you cannot set a flag to change the state of A to prevent notification, then you will have to send it with the change message. So you have 2 messages, one to update A (the general case) and another to quietly change A that is sent by B but still allows for changes to A to be triggered when others change it. I don't know how you make these updates so the implementation specifics is up to you.

  • Ok, thanks! This means that my approach isn't necessarily wrong, it's just that is difficult to achieve with Polymer.js. I will post a question on StackOverflow for specific details about the implementation. – Cristian Feb 26 '15 at 11:03
  • @Cristian, where's the stackoverflow question? I'm curious. – Jp_ Jan 30 '17 at 18:34
1

Generally you would have values A and B hidden using a mixin, changeable only through a method setA and setB (or better still by using a setter function). Internally, you would simply assign A or B directly without calling the setA or setB directly, and then call update() which triggers the event.

In other words, you'd have setA that assigns A and then resets the value of B without calling setB. Take a look at this quick example:

function Obj() {
  var A, B;

  function resetB() {
    console.log('Resetting B');
    B = '';
  }
  function update() {
    console.log('Values updated');
  }
  return {
    get A() { return A; },
    get B() { return B; },
    set A(aVal) { 
      A = aVal; 
      resetB(); 
      update();
    },
    set B(bVal) { 
      B = bVal;
      update(); 
    }
  };
}
var obj = new Obj();
obj.B = 'test';
// Console output:
// Values updated

// assert(obj.B == 'test')
obj.A = 'me';
// Console output:
// Resetting B
// Values updated

// assert(obj.A == 'me')
// assert(obj.B == '')
  • Thanks. This makes sense in vanilla Javascript but I am using Polymer which binds to object changes, so if I'm doing A = "new value" then the property watcher method gets triggered automatically (and asynchronously). I think though that this is not a place to discuss details of implementation though, I'll post on StackOverflow soon. – Cristian Feb 26 '15 at 11:39
  • 1
    @Cristian If this were a generic question on best practice, programmers SE would be best, though this seems specific to the language that you're using. In any case, I would see if you can't get Polymer to work on setter functions. If so, this would work (remove the call to update since the call is already being done by Polymer). – Neil Feb 26 '15 at 11:46
  • Hmm after giving some thought I think is quite a good idea. I'll have to see if the support for this is good enough to be used for client-side and how can it be integrated with Polymer's conventions. – Cristian Feb 26 '15 at 14:11
  • I found this: stackoverflow.com/questions/23900203/… – Cristian Feb 26 '15 at 14:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.