Search code examples
javascripthtmlreactjsweb-component

Extending a html component get attributes are not working


This is my code for custom webcomponent creation.

import S3Uploader from 'containers/S3Uploader';
import React from 'react';
import * as ReactDOM from "react-dom";

class Component extends HTMLElement {
  constructor() {
    super();
  }

  detachedCallback() {
    ReactDOM.unmountComponentAtNode(this);
  }

  createdCallback() {
    console.log("This attributes",this.attributes); //Why the attribute length is 0
    const props = this.getAllProps(this.attributes);
    console.log(props);
    const s3Config = JSON.parse(this.getAttribute('s3-config')); //This is null
    const handleUpload = eval(this.getAttribute('handle-upload'));
    console.log(s3Config,handleUpload);
    ReactDOM.render(<S3Uploader s3Config={s3Config} handleUpload={handleUpload}/>, this);
  }
  getAllProps(attributes) {
    let props = {};
    for (let i = 0; i < attributes.length; i++) {
      props[attributes[i].nodeName] = attributes[i].nodeValue;
    }
    return props;
  }
}



document.registerElement('s3-uploader',Component);

The problem is attributes length is 0 and all the attributes are null in createdCallback function.

So I am not able to pass the required attributes to react component.


Solution

  • Try converting to the V1 spec instead of the V0 spec:

    //import S3Uploader from 'containers/S3Uploader';
    //import React from 'react';
    //import * as ReactDOM from "react-dom";
    
    class Component extends HTMLElement {
      constructor() {
        super();
      }
    
      disconnectedCallback() {
        //ReactDOM.unmountComponentAtNode(this);
      }
    
      connectedCallback() {
        console.log("Attribute count",this.attributes.length); //Why the attribute length is 0
        const props = this.getAllProps(this.attributes);
        console.log(props);
        const s3Config = JSON.parse(this.getAttribute('s3-config')); //This is null
        const handleUpload = eval(this.getAttribute('handle-upload'));
        console.log(s3Config,handleUpload);
        //ReactDOM.render(<S3Uploader s3Config={s3Config} handleUpload={handleUpload}/>, this);
      }
      
      getAllProps(attributes) {
        let props = {};
        for (let i = 0; i < attributes.length; i++) {
          props[attributes[i].nodeName] = attributes[i].nodeValue;
        }
        return props;
      }
    }
    
    customElements.define('s3-uploader',Component);
    <s3-uploader s3-config='{"dog":12}' handle-upload="console.log('testing')"></s3-uploader>

    I commented out the react code so this would run in the test bed, but this works.

    The V0 spec is deprecated and soon to be dead. All components should be written using the V1 spec.