Search code examples
polymerpolymer-2.x

How can I compute a property based on another element's property?


I am trying to show/hide elements based on the availability of camera.

The detect-camera, camera-detached and create-welcome all are inside main create-app.

<link rel="import" href="../../bower_components/polymer/polymer-element.html">
<link rel="import" href="../../bower_components/polymer/lib/elements/dom-if.html">

<link rel="import" href="detect-camera.html">
<link rel="import" href="camera-detached.html">
<link rel="import" href="create-welcome.html">

<dom-module id="create-app">
  <template>
        <style>
            :host {
                display: block;
            }
        </style>

        <detect-camera found=[[found]]></detect-camera>
        <template is="dom-if" if="{{!allowed}}">
            <camera-detached></camera-detached>
        </template>
        <template is="dom-if" if="{{allowed}}">
            <create-welcome></create-welcome>
        </template>
  </template>
  <script>
    class CreateApp extends Polymer.Element {
      static get is() {
        return 'create-app';
      }

      constructor() {
        super();
      }

      static get properties() {
        return {
          allowed: {
            type: Boolean,
            computed: '_isAllowed(found)'
          }
        };
      }

      _isAllowed(found) {
        return found;
      }
    }

    window.customElements.define(CreateApp.is, CreateApp);
  </script>
</dom-module>

The camera-detached and create-welcome will be displayed on the logic, if or not the "found" property of detect-camera is true.

All the logic of detecting the camera is inside detect-camera. The code inside detect-camera sets its attribute "found" property/attribute.

<link rel="import" href="../../bower_components/polymer/polymer-element.html">

<dom-module id="detect-camera">
  <template>
  </template>

  <script>
    class DetectCamera extends Polymer.Element {
      static get is() {
        return 'detect-camera';
      }

      static get properties() {
        return {
          found: {
            type: Boolean,
            value: false,
            reflectToAttribute: true,
            notify: true
          }
        }
      }

      constructor() {
        super();
        this._foundChanged
      }

      _foundChanged() {
        this.found = true;
      }
    }

    window.customElements.define(DetectCamera.is, DetectCamera);
  </script>
</dom-module>

I want to compute the "allowed" based on the computed "found" property.


Solution

  • Use two-way binding:

    <detect-camera found="{{found}}"></detect-camera>
    

    or listen for the found property to change:

    <detect-camera on-found-changed="onFoundChanged"></detect-camera>
    

    If you use the event listener approach, you just need to update a local property in your CreateApp element:

    onFoundChanged(newVal, oldVal) {
      this.hasCamera = newVal;
    }