Skip to content

Angular 2Refresh Bound Variables from Callback

January 31st, 2017 - Software(1 min)

TL;DR: Use ChangeDetectorRef’s detectChanges() at the end of your callback code.

While developing my electron.js app, I’ve had the following workflow:

  • I have an input element and a button

  • The input element is capable of editing a path

  • The button triggers a File Open dialog

    <div class="list__search-field-wrap">
      <input
        #backupPath
        type="text"
        autofocus
        class="list__search-field input-padding-right"
        [(value)]="backup"
        (keyup.enter)="onEnter(backupPath.value)"
      />
    </div>
    <div class="list__search-btn-new" (click)="onBrowseFileOpen()">
      <i class="fa fa-folder-o"></i>
    </div>

The problem I had was the showOpenDialog() accepts a callback and I couldn’t get the input field to update once the user has picked a file. Fortunately, the smart angular developers have thought of this situation too and the solution is quite simple. You have to use ChangeDetectorRef like so:

import { Component, OnInit, isDevMode, ChangeDetectorRef } from '@angular/core'

@Component({
  selector: 'settings-paths',
  templateUrl: './paths.component.html'
})
export class PathsComponent implements OnInit {
  backup: string

  constructor(private ref: ChangeDetectorRef) {}

  onEnter(value: string) {
    console.log('update value')
  }

  onBrowseFileOpen(event) {
    remote.dialog.showOpenDialog(
      remote.getCurrentWindow(),
      {
        title: 'Select path',
        properties: ['openDirectory', 'createDirectory']
      },
      filenames => {
        if (filenames !== undefined && filenames.length > 0) {
          this.backup = filenames[0]
          this.onEnter(filenames[0])

          // HERE !
          this.ref.detectChanges()
        }
      }
    )
  }
}

The this.ref.detectChanges() at the end of the callback is the key to propagating the changes back throughout your angular code.

HTH,

Share on
Reddit
Linked in
Whatsapp

A little experiment: