DEV Community

Scott M Gerstl for TeamHive

Posted on

Passing an Object or Array to Stencil through markup

Common Code

export interface SomeValue {
  name: string;
  value: string;
}

Passing an Object

import { Component, h, Prop, Watch } from '@stencil/core';
import { SomeValue } from './some-value.interface';
@Component({
  tag: 'object-sample',
  styleUrl: '...',
  shadow: true
})
export class ObjectSample {
  private _objectData: SomeValue;
  @Prop() objectData: SomeValue | string;

  @Watch('objectData')
  objectDataWatcher(newValue: SomeValue | string) {
    if (typeof newValue === 'string') {
      this._objectData = JSON.parse(newValue);
    }
    else {
      this._objectData = newValue;
    }
  }

  componentWillLoad() {
    this.objectDataWatcher(this.objectData);
  }

  render() {
    return (
      <div class='object-data'>
        <span>{this._objectData.name}</span>
        <span>{this._objectData.value}</span>
      </div>
    );
  }
}
<object-sample 
   object-data='{"name": "Bird", "value": "Chirp"}'>
</object-sample>

Passing an Array

import { Component, h, Prop, Watch } from '@stencil/core';
import { SomeValue } from './some-value.interface';
@Component({
  tag: 'array-sample',
  styleUrl: '...',
  shadow: true
})
export class ArraySample {

  private _arrayData: SomeValue[];
  @Prop() arrayData: SomeValue[] | string;

  @Watch('arrayData')
  arrayDataWatcher(newValue: SomeValue[] | string) {
    if (typeof newValue === 'string') {
       this._arrayData = JSON.parse(newValue);
    }
    else {
      this._arrayData = newValue;
    }
  }

  componentWillLoad() {
    this.arrayDataWatcher(this.arrayData);
  }

  render() {
    return [
      <div class='array-size'>{ this._arrayData.length }</div>,
      this._arrayData.map(x =>
        <div class='row'>
          <span>{x.name}</span>
          <span>{x.value}</span>
        </div>
      )
    ];
  }
}
<array-sample 
   array-data='[{"name": "Cat", "value": "Meow"}, {"name": "Dog", "value": "Woof"}]'>
</array-sample>

Key Concepts

  • The @Prop() datatype must contain string if a type is defined
  • Use a @Watch() function to parse the json string value
  • Call the @Watch() function in the componentWillLoad() function for the first parse of the json data
    • The @Watch() function does not fire on the first load of the component
  • The value passed to the @Prop() must follow strict json syntax

Version Consideration

These examples are Stencil One. If you are using pre @stencil/core@one Check out the Breaking changes document to see what updates are needed to get this sample to work for you in the beta

Discussion (0)