Looping through children components in a LitElement template

I aim to generate <slot>s for each child element. For instance, I have a menu and I intend to place each child inside a <div> with a item class.
To achieve this, I have devised a small utility function for mapping the children:

export function ChildrenMap(el: LitElement, map: (el: HTMLElement, index: number) => TemplateResult): TemplateResult[] {
    console.log(el.children.length) // It returns 0 in browsers like Google Chrome and possibly Edge.
    return (Array.prototype.slice.call(el.children) as HTMLElement[])
                .map(map);
}

Subsequently, I utilize this function in the render method:

render() {
    return html`
        <nav>
        ${ChildrenMap(this, (ele, index) => {
            let id = ele.id ? ele.id : `item-${index}`;
            ele.setAttribute('slot', id);

            let klass = 'item';
            if (this.selected && this.selected == index) {
                klass += " selected";
            }

            return html`
                <div class="${klass}" data-index="${index}">
                <slot name="${id}"></slot>
                </div>`;
        })}
        </nav>
    `;
}

While this code operates smoothly in FireFox, in Google Chrome, the element is devoid of children during rendering, leading to an empty <nav> element. Can anyone clarify why the element has no children at the moment of rendering? If I am approaching this incorrectly, are there any alternate methods to accomplish this task?

Thank you

Answer №1

Update: The bug reported in Mozilla/FireFox has been resolved in early 2021

FireFox is currently incorrect as it triggers the connectedCallback too late

The bug has been acknowledged by Mozilla engineer Anne van Kesteren:

For more information, refer to the discussion on StackOverflow:

  • Wait for Element Upgrade in connectedCallback: FireFox and Chromium differences

During the execution of the connectedCallback, there are no DOM children to read as they are still being parsed. This could be particularly relevant in cases with a large DOM structure

The suggested workaround is to introduce a delay:

connectedCallback(){
  setTimeout(()=>{
    // now you can access the DOM children
  },0);
}

Various suggestions involving Promises essentially aim to achieve the same goal: Waiting for the Event Loop to be empty

  • Curious about the Event Loop? - Check out Philip Roberts' explanation
    Event Loop Video

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Prisma unexpectedly updates the main SQL Server database instead of the specified database in the connection string

I have recently transitioned from using SQLite to SQL Server in the t3 stack with Prisma. Despite having my models defined and setting up the database connection string, I am encountering an issue when trying to run migrations. Upon running the commands: ...

Error suddenly appeared when trying to serve a previously functional project locally: Firebase function module not found

After not making any changes to my firebase-related files, I suddenly started encountering the following issue that I just can't seem to figure out: We were unable to load your functions code. (see above) - It appears your code is written in Types ...

Incorporating regular expressions to extract a specific string from a URL is a requirement

Can anyone assist with extracting a specific string using regex in TypeScript? I have the following URL: https://test.io/content/storage/id/urn:aaid:sc:US:8eda16d4-baba-4c90-84ca-0f4c215358a1;revision=0?component_id=e62a5567-066d-452a-b147-19d909396132 I ...

The 'Group' type is lacking the 'children' properties needed for the 'Element' type in Kendo UI Charts Drawing when using e.createVisual()

In my Angular 10 project, I utilized the following function to draw Kendo Charts on Donut Chart public visual(e: SeriesVisualArgs): Group { // Obtain parameters for the segments this.center = e.center; this.radius = e.innerRadius; // Crea ...

A guide to setting properties using a Proxy object

Within my class, I have included a Proxy which is structured as follows: export class Row<T extends ModelItems> { private _row: T = <T>{} public constructor(rowItems?: T) { if (rowItems) { this._row = rowItems } return new Proxy( ...

Leveraging the power of NextJs and the googleapis Patch function to seamlessly relocate files and folders to a specific

I am currently working on a functionality to move specific files or folders to another folder using nextjs + googleapis. Here is the code I have been testing: const moveFileOrFolder = async () => { if (!session || !selectedItemId || !destinationFolder ...

Which specific files do I have to edit in order for Laravel to acknowledge a new data type?

Currently, I am honing my skills in Laravel by working on a Laravel Breeze application. One task that I have set for myself is to incorporate a postal code field into the existing User model, including the registration form. To tackle this challenge, I dec ...

Guide to transforming a TaskOption into a TaskEither with fp-ts

I have a method that can locate an item in the database and retrieve a TaskOption: find: (key: SchemaInfo) => TO.TaskOption<Schema> and another method to store it: register: (schema: Schema) => TE.TaskEither<Error, void> Within my regis ...

Utilize TypeScript to define the types based on the return values produced by an array of factory functions

My application features multiple factory functions, each returning an object with specific methods (more details provided below). I am interested in creating a type that combines the properties of all these returned objects. const factoryA = () => ({ ...

Next.js routes handlers do not have defined methods parameters

Struggling to find the cause of undefined params Currently delving into the world of Nextjs api routes, I keep encountering an issue where my params are coming up as undefined when trying to use them in the HTTP method. My setup includes prisma as my ORM ...

Error message: Unable to assign type (Combining React, Typescript, and Firebase)

Just started using TypeScript and in the process of migrating my React app to incorporate it. Encountering some type issues with Firebase auth service that I can't seem to find a solution for. Any suggestions? import React, { useEffect, useState } f ...

Discovering the title of a page in layout using Nextjs 13

How do I extract the title stored in the metadata object within the layout.tsx file? page.tsx: import { Metadata } from 'next'; export const metadata: Metadata = { title: 'Next.js', }; export default function Page() { return &a ...

What's the best way to implement satisfies with a generic type?

In my development process, I am working with components that have default values combined with props. To streamline this process, I created a single function for all components: export function getAssignProps <T extends {}>(propsMass:T[]){ return ...

Obtain the count of unique key-value pairs represented in an object

I received this response from the server: https://i.stack.imgur.com/TvpTP.png My goal is to obtain the unique key along with its occurrence count in the following format: 0:{"name":"physics 1","count":2} 1:{"name":"chem 1","count":6} I have already rev ...

What is the best way to utilize a reduce function to eliminate the need for looping through an object in JavaScript?

Currently, my code looks like this: const weekdays = eachDay.map((day) => format(day, 'EEE')); let ret = { Su: '', Mo: '', Tu: '', We: '', Th: '', Fr: '', Sa: '' }; w ...

Achieving the incorporation of multiple components within a parent component using Angular 6

Within parent.component.html The HTML code I have implemented is as follows: <button type="button" class="btn btn-secondary (click)="AddComponentAdd()">Address</button> <app-addresse *ngFor="let addres of collOfAdd" [add]="addres">< ...

Why is it not possible to convert from any[] to MyType[] in TypeScript?

Within TypeScript, the any type allows for casting to and from any arbitrary type. For example, you can cast from a variable of type any to a variable of type MyArbitraryType like so: var myThing: MyArbitraryType; var anyThing: any; myThing = anyThing; / ...

Tips for utilizing intellisense from monaco.d.ts

Is there a way for me to incorporate monaco.d.ts in order to utilize intellisense with the monaco-editor package? I've recently integrated this package into a JavaScript project and everything is functioning properly. However, as I transition to Type ...

Please input the number backwards into the designated text field

In my react-native application, I have a TextInput where I need to enter numbers in a specific order such as 0.00 => 0.01 => 0.12 => 1.23 => 12.34 => 123.45 and so on with each text change. I tried using CSS Direction "rtl" but it didn' ...

How can contextual binding be implemented in TypeScript?

In Laravel, you have the option to specify which class should be imported if a particular class is accessed. For example, if someone tries to use the Filesystem contract, it will return the Storage Facade (Laravel Contextual Binding). Similarly, if someo ...