Lodea
Lodea

Reputation: 189

Is it possible to initialize methods and properties in object initialization?

For example to minimize code like:

return (()=> {
        let c = document.createElement("col");
        c.appendChild((()=>{
            let p = document.createElement("p");
            p.innerText = "Hello";
            return p;
        })());
        c.appendChild((()=>{
            let p = document.createElement("p");
            p.innerText = "World";
            return p;
        })());
        return c;
    })();

or:

let col = document.createElement("col");
let title0 = document.createElement("p");
title0.innerText = "Hello";
let title1 = document.createElement("p");
title1.innerText = "World";
col.appendChild(title0);
col.appendChild(title1);
return col;

into something along the lines of:

return document.createElement("col", {
    appendChild(document.createElement("p", {
        innerText = "Hello"
    })),
    appendChild(document.createElement("p", {
        innerText = "World"
    }))
});

I know field initializers exist (Which is what I based my pseudocode on), but is it possible to do something similar with methods and properties?

Upvotes: 0

Views: 48

Answers (2)

Lodea
Lodea

Reputation: 189

I managed to find an answer eventually:

export const Elem = <K extends keyof HTMLElementTagNameMap>(tagName: K, properties: Partial<HTMLElementTagNameMap[K]>, children: Node[]) => {
    const element = document.createElement(tagName);
    Object.assign(element, properties);
    for (const child of children) {
        element.appendChild(child);
    }
    return element;
}

Example usage:

Elem("div", {}, [
    Elem("p", {
        innerText: "Hello"
    }, []),
    Elem("p", {
        innerText: "world"
    }, [])
]);

No need for HTML or React.

Upvotes: 0

CertainPerformance
CertainPerformance

Reputation: 370659

Just construct and return an HTML string.

return `
  <col>
    <p>Hello</p>
    <p>World</p>
  </col>
`;

And then use insertAdjacentHTML to put it into the DOM.

If you absolutely need an element, not a string, then you can explicitly create only one (the container), and set its .innerHTML.

const col = document.createElement('col');
col.innerHTML = `
  <p>Hello</p>
  <p>World</p>
`;
return col;

Or (as I'd prefer), use a framework like React.

const MyCol = () => (
  <col>
    <p>Hello</p>
    <p>World</p>
  </col>
);

Upvotes: 1

Related Questions