Search code examples
javascriptdata-bindingpolymerlit-elementlit-html

Lit-Element binding to svg image. TypeError: Cannot read property 'split' of null


I've been trying to bind a simple url (string) to an image tag inside a svg element.
But I am receiving following error: TypeError: Cannot read property 'split' of null and no picture is displayed in the browser.

The image as well as the binding work fine and without error inside a normal <img> tag or hardcoded in the <image/> element.

Example with SVG:

import { LitElement, svg } from 'lit-element';

class AppDevice extends LitElement {
static get properties() {
    return {
        selectedImage: {
            type: String
        }
    };
}

constructor() {
    super();
    this.selectedImage = 'https://mdn.mozillademos.org/files/6457/mdn_logo_only_color.png';
}

render() {
    return svg`

        <svg width="600px" height="600px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

             <image xlink:href="${this.selectedImage}" id="canvas" x="176.32" y="145.932" width="252.068" height="252.068"/>
             <!-- Works -->
             <!-- <image xlink:href="https://mdn.mozillademos.org/files/6457/mdn_logo_only_color.png" id="canvas" x="176.32" y="145.932" width="252.068" height="252.068"/>      -->

        </svg>

`;
}
}

Example with workaround:

After reading the discussion on github that was pointed out in the comments f this question, I've updated my answer:

enter image description here

const namespaced = directive((namespace, value) => (part) => {
       part.committer.element.setAttributeNS(namespace, part.committer.name, value);
    });

const xlinkNamespace = 'https://mdn.mozillademos.org/files/6457/mdn_logo_only_color.png';

import { LitElement, html } from 'lit-element';

class AppDevice extends LitElement {
  static get properties() {
    return {
    };
   }

constructor() {
  super();
}

render() {
   return html`

    <svg width="600px" height="600px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

      <image xlink:href="${namespaced(xlinkNamespace, 'something')}" id="canvas" x="176.32" y="145.932" width="252.068" height="252.068"/>

    </svg>

    `;
}
}

Solution

  • As I wasn't able to get the example from the comments to work I came up with a different solution to my problem. Although this isn't the exact answer I was looking for, I figured that posting it here might be still a good idea.

    Without further ado here my solution:
    I made use of css clip-path to display an image inside my SVG element and in particular be able to switch it via bindings.

    Here is an article about clipping and masking

    <img .src="${this.selectedimg}" style="clip-path: url(#myClip);" width="250" height="250">
    
    <svg>
      <defs>
        <clipPath id="myClip">
          <rect width="250" height="250"/>
        </clipPath>
      </defs>
    </svg>