Lit-html: Using repeat directive is not working

Created on 10 May 2018  ยท  15Comments  ยท  Source: Polymer/lit-html

Hi, I created this code snippet

const items = [
  {
    id: 0,
    label: 'Hey'
  },
  {
    id: 1,
    label: 'Hey'
  }
];

const template = (self) => html`
  <nav class="header-navigation">
    <ul class="navigation-list">
    ${repeat(items, (i) => i.id, (i, index) => html`
      <li>${index}: ${i.label}</li>`)}
    </ul>
  </nav>
`;

and it returns an error

repeat.js:38 Uncaught Error: repeat can only be used on NodeParts
    at part (repeat.js:38)
    at getValue (element-lite.umd.js:1686)
    at NodePart.setValue (element-lite.umd.js:1763)
    at TemplateInstance.update (element-lite.umd.js:1909)
    at NodePart._setTemplateResult (element-lite.umd.js:1822)
    at NodePart.setValue (element-lite.umd.js:1775)
    at TemplateInstance.update (element-lite.umd.js:1909)
    at render (element-lite.umd.js:1489)
    at HTMLElement.invalidate (element-lite.umd.js:2117)
    at HTMLElement.connectedCallback (element-lite.umd.js:2099)

Am i doing something wrong?

Most helpful comment

Also check your dependencies, lit-element is at version 0.5.1 as of writing this. You should not need to install lit-html separately.

Check out https://github.com/Polymer/pwa-starter-kit for a starter kit using LitElement. The wiki at https://github.com/Polymer/pwa-starter-kit/wiki contains many helpful demo apps with source codes.

Particularly, https://github.com/PolymerLabs/polymer-redux-hn/blob/master/src/components/hn-list.js uses LitElement and repeat, may be useful to study.

Admittedly, going the LitElement route is unnerving and at times feels like re-inventing the wheel. (someone get me an advanced router for LitElement, anyone?) Really tempted by Vue and all that. Take your pick between magic and standards-based.

All 15 comments

How did you import repeat? It should be coming from import {repeat} from "lit-html/lib/repeat"

I'm currently unable to reproduce this with the code in the OP (plunker where the code works), could you provide a code sample where the error actually occurs (e.g. a plunker)? Does this happen in all browsers? (maybe it works for me because it's only broken for a certain browser/version)

@ernsheong yep I did import it :)

@bgotink I'm using it as part of shadow dom. I'm going to create a small repo for it.

same error, sounds like similar or the same usage as follows:

source excerpt:
import { LitElement, html } from '@polymer/lit-element/lit-element.js';
import { repeat } from '@polymer/lit-element/node_modules/lit-html/lib/repeat.js';

class ThisProblem extends LitElement{
    _render(){
return html`
  <ul>
    ${repeat([{name:'stuff'},{name:'things'},{name:'lastly'}], (i) => i.id, (i, index) => html`
      <li>${index}: ${i.name}</li>`)}
  </ul>
`;
...excerpt ends...

lit-html near line 31:
    return directive((part) => {
        if (!(part instanceof NodePart)) {
            throw new Error('repeat can only be used on NodeParts');
        }

error:
repeat.js:31 Uncaught Error: repeat can only be used on NodeParts
    at directive (repeat.js:31)
    at getValue (lit-html.js:334)
    at NodePart.setValue (lit-html.js:420)
    at TemplateInstance.update (lit-html.js:576)
    at render (lit-html.js:130)
    at render (shady-render.js:35)
    at HTMLElement._applyRender (lit-element.js:182)
    at HTMLElement._propertiesChanged (lit-element.js:132)
    at HTMLElement._flushProperties (properties-changed.js:335)
    at HTMLElement._flushProperties (lit-element.js:142)

npm ls excerpt
โ”€โ”ฌ @polymer/[email protected]
โ”‚ โ”œโ”€โ”€ @polymer/[email protected] deduped
โ”‚ โ””โ”€โ”€ [email protected]

browser: Chrome-current on macOS 10.13.4

if I adapt the above excerpt to change where repeat is imported the error goes away and the repeat does nothing (renders an empty unordered list element):

import { LitElement } from '@polymer/lit-element/lit-element.js';
import { html } from '@polymer/lit-element/node_modules/lit-html/lit-html.js';
import { repeat } from '@polymer/lit-element/node_modules/lit-html/lib/repeat.js';
...rest is the same as above...

At this point I lack insight into what these various packages are trying to accomplish and had intended to use them to focus on solving other practical problems.

@jimmont

You can simply import using:
import {LitElement, html} from "@polymer/lit-element"; import {repeat} from "lit-html/lib/repeat"

Anyways, in your example, your objects are missing the id property?
{name:'stuff'},{name:'things'},{name:'lastly'} should be {id: 1, name:'stuff'},{id: 2, name:'things'},{id: 3, name:'lastly'}

thanks @ernsheong, the problem is unrelated to the missing id--it has to do with the classes I'm importing and how they're intended to be used, which is still a mystery to me. I found and started reading the very helpful material at https://polymer.github.io/lit-html/guide/#template-dialects-lit-html-vs-lit-extended (found via https://github.com/Polymer/lit-element/issues/63).

the following change (inexplicably) fixes my previous _render (above):

import { repeat } from 'lit-html/lib/repeat.js';
import { html } from 'lit-html/lib/lit-extended.js';
import { LitElement } from '@polymer/lit-element/lit-element.js';

also (separately) using @ernsheong's suggestion this  works too:

import { LitElement, html } from '@polymer/lit-element/lit-element.js';
import { repeat } from 'lit-html/lib/repeat.js';

strange, not sure why or how this is any different than previous attempts

I'm pretty tired so the reason might be obvious--I'd really like to better understand how this was intended to work. Feel like I'm losing a lot of time on something that should be straightforward.

Also check your dependencies, lit-element is at version 0.5.1 as of writing this. You should not need to install lit-html separately.

Check out https://github.com/Polymer/pwa-starter-kit for a starter kit using LitElement. The wiki at https://github.com/Polymer/pwa-starter-kit/wiki contains many helpful demo apps with source codes.

Particularly, https://github.com/PolymerLabs/polymer-redux-hn/blob/master/src/components/hn-list.js uses LitElement and repeat, may be useful to study.

Admittedly, going the LitElement route is unnerving and at times feels like re-inventing the wheel. (someone get me an advanced router for LitElement, anyone?) Really tempted by Vue and all that. Take your pick between magic and standards-based.

yes @ernsheong npm install and dedupe are the steps used to get these packages and I just imported them wherever they land. The import for repeat changed so perhaps that was somehow a source of the problem. Seems a bit strange. thanks for the info--yes I've been working a bit from this starter kit, super helpful

on a side note: I've been using native web components since mid last year and they're great, much easier than anything else so-far (that I've taken time to use), seemed relevant to mention this when qualifying effort using web components vs polymer/lit-* vs anything else.

I'm having the same issue and it seems to stem from multiple packages having lit-html as a dependency, Webpack imports, and where npm puts packages.

The compiled version of [email protected] has this in it:

if (!(part instanceof NodePart)) {
    throw new Error('repeat can only be used on NodeParts');
}

After Webpack processes that you get something like the following:

    if (!(part instanceof _lit_html_js__WEBPACK_IMPORTED_MODULE_0__["NodePart"])) {
        throw new Error('repeat can only be used on NodeParts');
    }
  • part has a function location of node_modules/@nutmeg/seed/node_modules/lit-html/lit-html.js
  • _lit_html_js__WEBPACK_IMPORTED_MODULE_0__["NodePart"] has a function location of node_modules/lit-html/lit-html.js

Both lit-htmls are v0.10.0 so I'm not sure why npm isn't deduping them.

> npm ls lit-html
[email protected] /Users/abraham/dev/node-package
โ”œโ”€โ”ฌ @nutmeg/[email protected]
โ”‚ โ””โ”€โ”€ [email protected]
โ””โ”€โ”€ [email protected]

...

After some further exploration, I deleted node_modules and package-lock.json and installed dependancies again.

Now the error is gone and the packages are showing as deduped.

> npm ls lit-html
[email protected] /Users/abraham/dev/node-package
โ”œโ”€โ”ฌ @nutmeg/[email protected]
โ”‚ โ””โ”€โ”€ [email protected]  deduped
โ””โ”€โ”€ [email protected]

This does look like a duplication problem (another symptom is rendering [object Object] instead of nested templates. Not sure what we can do in the library. instanceof is a pretty important test to use, we could duck-type, but we've had changes to the internal APIs recently where that would break anyway.

I'm going to start being much more careful with revving the minor version before we hit 1.0 so hopefully there will be less duplication.

I've got both of these problems (repeat broken, [object Object]). I'm using rollup and npm to build.

Is there anything I can do on my end? I'm hoping to work this out so I can publish a library of Apollo GraphQL base classes based on LitElement.

The exact same code works fine if it's imported as a relative path from within the consuming app's src files.

e.g.

/* src/components/foo-element/foo-element.js */
import { ApolloQuery } from 'lit-apollo/apollo-query' // `[object Object]`
import { ApolloQuery } from '../lit-apollo/apollo-query' // works

@bennypowers try making sure that everything is using the same version of lit-html and then run npm dedup.

With the help of @ruphin, I solved the problem by applying the following plugin to my rollup config. It ensures that any module importing lit-element imports only the version maintained by the top-level app.

import includepaths from 'rollup-plugin-includepaths';
const plugins = [
  includepaths({
    include: {
      // only use app's version of lit-element
      '@polymer/lit-element': 'node_modules/@polymer/lit-element/lit-element.js',
      // when using `includepaths`, if two modules share the same name, it can cause clobberage.
      'shaka-player': 'node_modules/shaka-player/dist/shaka-player.compiled.js', 
    },
  }),
  ...etc
];

TBH this feels like a bad hack, but I'm at a loss for a better solution, given the current state of the platform. I really hope something like https://github.com/npm/npm/issues/20185 lands shortly so that developers can deal sanely with these types of scenarios.

Ironically, I came across this issue myself now after upgrading to latest LitElement. I can confirm that npm dedupe helped.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Christian24 picture Christian24  ยท  4Comments

depeele picture depeele  ยท  3Comments

AndyOGo picture AndyOGo  ยท  3Comments

MVSICA-FICTA picture MVSICA-FICTA  ยท  5Comments

pjtatlow picture pjtatlow  ยท  3Comments