• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

I Like Kill Nerds

The blog of Australian Front End / Aurelia Javascript Developer & brewing aficionado Dwayne Charrington // Aurelia.io Core Team member.

  • Home
  • Aurelia 2
  • Aurelia 1
  • About
  • Aurelia 2 Consulting/Freelance Work

Working With Aurelia @observable

Aurelia 1 · June 3, 2016

Even if you are new to Aurelia, you are probably familiar with the @bindable functionality which allows you to add bindable attributes primarily to your custom elements and custom attributes.

There is a lesser known feature in Aurelia in the form of @observable which allows you to use the underlying observation layer in Aurelia to observe variables for changes and react accordingly in a similar way you react to changes on @bindable attributes.

@observable In Action

import { observable } from 'aurelia-framework';

export class MyViewModel {
    @observable myVariable;

    attached() {
        setTimeout(() => {
            this.myVariable = 'I am a value, hooray!';
        }, 5000);
    }

    myVariableChanged(newValue, oldValue) {
        console.log(newValue, oldValue);
    }
}

Once the view-model attaches itself to the page, it’ll wait 5 seconds and then change the value. This will then trigger the changed callback defined on the view-model.

The naming convention is <variableName>Changed with two parameters on the changed callback, the new value and the old value.

The variableChanged part is a convention. Aurelia takes for supplied class value and appends Changed to the end. If you do not like this kind of magic, you can explicitly configure the observable decorator to define the callback.

import { observable } from 'aurelia-framework';

export class MyViewModel {
    @observable({changeHandler: 'myVariableChanged'}) myVariable;

    attached() {
        setTimeout(() => {
            this.myVariable = 'I am a value, hooray!';
        }, 5000);
    }

    myVariableChanged(newValue, oldValue) {
        console.log(newValue, oldValue);
    }
}

This does the exact same thing as the previous example, we are just being more explicit. This allows you to also change the change callback function. If you wanted your change handler to be called ‘myExplicitChangeHandler` then you’d do this:

@observable({changeHandler: 'myExplicitChangeHandler'}) myVariable;

myExplicitChangeHandler(newValue, oldValue) {
    console.log(newValue, oldValue);
}

The beautiful thing about the @observable decorator is behind the scenes all it does is create a setter and getter on your property but also declares any dependencies your property has which is the equivalent of @computedFrom which prevents dirty-checking.

There are other ways you can observe changes on custom objects and arrays, one such alternative is using the BindingEngine and observation methods, specifically propertyObserver if you want to observe changes on objects.

Dwayne

Leave a Reply Cancel reply

9 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Andrés
Andrés
6 years ago

Does it detect `myVariableChanged` by convention? In that case I think that I still prefer explicit Knockout Observables…

0
Dwayne
Dwayne
Author
6 years ago

@Andres

Behind the scenes observable just defines standard setter/getters for your properties and registers a change event listener. You can define what the callback function is just like you can using a `@bindable`

0
Andrés
Andrés
6 years ago

I understand, but in my opinion this kind of ~~magic~~ conventions is not good.

0
Eric Robishaw
Eric Robishaw
6 years ago

Andres, it’s really not “magic”. If it has the attribute @bindable, or @observable, it gets called, otherwise, it does not get called.

Adding the attribute is just a shortcut, not magic at all.

BTW, for anyone reading…
Unless I just have syntax wrong, it appears that @bindable and @observable will NOT invoke a lambda expression, i.e.,
nameChanged =(old,newval)=>{
//does not get called
}

0
eliav
eliav
6 years ago

where should i import observable from?

0
Anthony McKale
Anthony McKale
5 years ago

observable is in ‘aurelia-framework’

Also nice stuff in ‘aurelia-framework’

bindable, computedFrom, inject

0
Matt
Matt
5 years ago

I noticed there is no dispose/unsubscribe in your examples. Is the event listener disposed of automatically when the component deactivates?

0
Duke Fleed
Duke Fleed
4 years ago

i was insiting using @bindable, thanks you saved my day, again 🙂

0

Primary Sidebar

Popular

  • Testing Event Listeners In Jest (Without Using A Library)
  • How To Get The Hash of A File In Node.js
  • Thoughts on the Flipper Zero
  • Waiting for an Element to Exist With JavaScript
  • How To Paginate An Array In Javascript
  • How to Use Neural DSP Archetype Plugins With the Quad Cortex
  • How To Mock uuid In Jest
  • How To Get Last 4 Digits of A Credit Card Number in Javascript
  • NBN Box Installed Inside of Garage, Where Do You Put The Modem?
  • How To Decompile And Compile Android APK's On A Mac Using Apktool

Recent Comments

  • Kevmeister68 on Start-Ups and Companies That Embrace Work From Anywhere Will Be More Likely to Survive the Coming Recession in 2023
  • kevmeister68 on What Would Get People Back Into the Office?
  • Dwayne on PHP Will Not Die
  • Dwayne on How to Create a Blockchain With TypeScript
  • kevmeister68 on PHP Will Not Die

Copyright © 2023 · Dwayne Charrington · Log in

wpDiscuz