I have created a backend function which returns an array. In the front-end I call this function and pass array (with JSON stringify) to the custom element using setAttribute API.
In the custom element I parse incoming array and create custom components with it. Problem is how could I await incoming attribute because custom element is not waiting it just checking attribute and gets null. And it’s not working just because of this I added timeout and tested what would happen it would wait and it’s working when it’s able to get data from front-end.
How can I make async await system between frontend and custom element? Here is the codes:
Front-end:
import { stateChanger } from 'public/Utilities/Utilities.js'
import { getAvailableProducts } from 'backend/Support/Custom-Setup-System/data.jsw'
$w.onReady(function () {
getAvailableProducts()
.then((results) => {
console.log(results)
$w("#productSelectorElement").setAttribute("data", JSON.stringify(results))
$w("#productSelectorElement").on('onClick', event => {
console.log(event.detail)
});
})
});
Custom Element:
const createStyle = () => {
let style = document.createElement('style');
style.innerHTML = `
p {
color: white;
font-family: Poppins;
font-size: 16px;
padding: 0;
margin: 0;
cursor: pointer;
}
h4 {
color: white;
font-family: Poppins;
font-weight: 500;
font-size: 20px;
margin: 0;
padding: 0;
}
.grid {
width: var(--customElementWidth);
display: grid;
grid-template-columns: repeat(5, minmax(150px, auto));
grid-auto-rows: minmax(170px, auto);
justify-content: center;
align-items: center;
grid-gap: 20px;
}
.container {
--state: none;
--opacity: 0;
width: 150px;
height: 170px;
display: grid;
justify-content: center;
align-items: center;
grid-template-columns: repeat(2, 1fr);
border: none;
border-radius: 15px;
background-color: white;
transition: 0.3s ease-in-out;
cursor: pointer;
}
.content {
height: 130px;
display: var(--state);
grid-template-rows: 1fr 1fr;
grid-gap: 5px;
margin-left: -50px;
margin-right: 20px;
justify-content: start;
align-items: center;
animation: opacity 0.4s ease-in;
}
.image {
display: grid;
justify-content: start;
align-items: center;
}
.image img {
object-fit: cover;
height: 130px;
width: 110px;
border-radius: 15px;
margin-left: 20px;
}
.container:hover {
background-color: green;
width: 400px;
--state: grid;
cursor: pointer;
}
.title {
align-self: end;
}
.text {
margin-top: 4px;
align-self: start;
}
@keyframes opacity {
from {
opacity: 0;
display: none;
}
to {
opacity: 1;
display: grid;
}
}
`
return style;
}
let innerHtml = (idIdentity) => {
let html = `
<div class="image">
<img id="image${idIdentity}" src="./normal-gölgesiz.png" alt="">
</div>
<div class="content">
<h4 class="title" id="title${idIdentity}">Yayıncı Paketi</h4>
<p class="text" id="text${idIdentity}">Seçmek İçin Tıklayın</p>
</div>
`
return html;
}
const createGrid = () => {
const grid = document.createElement('div')
grid.className = "grid";
return grid;
}
const createProductTab = (item, idIdentity) => {
const productTab = document.createElement('div');
productTab.className = "container";
productTab.id = `container${idIdentity}`;
productTab.innerHTML = innerHtml(idIdentity);
let hoverColor;
if (item.isSelectable === true) {
hoverColor = "#008765"
} else {
hoverColor = "#E03131"
}
productTab.addEventListener('mouseover', () => {
productTab.style = `background-color: ${hoverColor}`
})
productTab.addEventListener('mouseout', () => {
productTab.style = "background-color: white"
})
productTab.querySelector(`#image${idIdentity}`).src = item.productImage;
productTab.querySelector(`#title${idIdentity}`).innerText = item.productTitle;
productTab.querySelector(`#text${idIdentity}`).innerText = item.reasonText;
return productTab;
}
class ProductTab extends HTMLElement {
constructor() {
super();
this.showInfo = true;
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(createStyle());
this.shadowRoot.appendChild(createGrid())
}
async getData() {
return await JSON.parse(this.getAttribute("data"))
}
async setupProductTab() {
let main = this;
let data = await this.getData()
data.forEach((item, index) => {
this.shadowRoot.querySelector('.grid').appendChild(createProductTab(item, index))
this.shadowRoot.querySelector(`#container${index}`).addEventListener('click', event => {
main.dispatchEvent(new CustomEvent('onClick', { detail: item }));
})
})
}
async connectedCallback() {
console.info("Connected")
this.setupProductTab()
}
disconnectedCallback() {
console.error("Disconnected!")
}
}
window.customElements.define('product-tab', ProductTab);
I even tried to use while and for loop even like a noob I tried setInterval non of them worked xd.
Any answer?