Updating DynamicObject property in ValueTree - listeners not triggered

One of my ValueTree children holds a DynamicObject property. I can update and modify this object without any problems, but doing so does not triggering any ValueTree::Listener methods. Is this a known limitation or should this work?

Maybe it’s worth mentioning that I’m modifying the object by way of a Value which is retrieved using the getPropertyAsValue() method. But this works absolutely fine for all other property types.

FWIW, here is some simple code demonstrating the issue. The valueTreePropertyChanged() method is never triggered, even though one of the valueTree properties is being updated?

 The block below describes the properties of this PIP. A PIP is a short snippet
 of code that can be read by the Projucer and used to generate a JUCE project.


  name:             MyComponentPIP

  dependencies:     juce_core, juce_data_structures, juce_events, juce_graphics, juce_gui_basics
  exporters:        XCODE_MAC


  type:             Component
  mainClass:        MyComponent



#pragma once

class MyComponent  : public juce::Component, public ValueTree::Listener
    MyComponent(): valueTree("testValueTree")
        setSize (600, 400);
        juce::ValueTree child("child");
        child.setProperty("DyObj", new juce::DynamicObject(), nullptr);
        valueTree.addChild(child, -1, nullptr);
        auto childNode = valueTree.getChild(0);
        //update/change the object
        childNode.getProperty("DyObj").getDynamicObject()->setProperty("NewData", "a string");

    ~MyComponent() override   {}

    void valueTreeChildAdded (juce::ValueTree& parentVt, juce::ValueTree& newVt)
    void valueTreePropertyChanged(juce::ValueTree& vt, const juce::Identifier& prop)
    void paint (juce::Graphics& g) override   {}

    void resized() override {}

    //ValueTree::Listener virtual methods....

    void valueTreeChildRemoved (juce::ValueTree&, juce::ValueTree&, int) override {}
    void valueTreeChildOrderChanged (juce::ValueTree&, int, int) override {}
    void valueTreeParentChanged (juce::ValueTree&) override {}

    // Your private member variables go here...
    ValueTree valueTree;


I’ve run into this as well. You only get a callback if you change to a different DynamicObject. You do not get callback if you change the properties within the DynamicObject.

You could just call sendPropertyChangeMessage manually.


Thanks @matt :+1: I’m not sure how I missed that sendPropertyChangeMessage() method :see_no_evil: That will do the trick nicely.

Close, but no cigar just yet. If I call getPropertyAsValue() and assign to a value, and then call that value’s getValueSource().sendChangeMessage(true); it once again fails to trigger any ValueTree listeners:

        juce::ValueTree child("child");
        juce::var obj = new juce::DynamicObject();
        child.setProperty("DyObj", obj, nullptr);
        valueTree.addChild(child, -1, nullptr);
        auto childNode = valueTree.getChild(0);
        childNode.getProperty("DyObj").getDynamicObject()->setProperty("NewData", "a string");
        value = childNode.getPropertyAsValue("DyObj", nullptr);
        value.getValue().getDynamicObject()->setProperty("MoreNewData", "a string");
        //this doesn't trigger..
        //this triggers..

I can always pass the entire ValueTree to my property component, but I’d like to know if this is expected behaviour or is something broken somewhere?

Try childNode.sendPropertyChangeMessage(“DyObj”).

Calling value.getValueSource().sendChangeMessage(true) will generate callbacks to Value::Listener::valueChanged, not ValueTree::Listener::valueTreePropertyChanged.


Yes, I had that marked in my code as working fine. Thanks for the full break down. It’s clear how I can work with this now, and I’m happy to say everything is now working as it should be. Thanks again :+1:

Yes, I had that marked in my code as working fine.
Right, so you did; I missed that. Glad you’ve got it all sorted out.


1 Like

I just came across the ValueTreePropertyWithDefault class. Seems like this might be a better choice for me in this instance. :+1: