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?
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.jsBoth 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.
Most helpful comment
Also check your dependencies, lit-element is at version
0.5.1as 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
LitElementandrepeat, 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.