I use one javascript to build my html page using templates (PageBuilder) and another to translate the content Translator. Problem is that the page has to be fully built before translating it otherwise some items are not found by Translator when it loads, and that's what happens here.
From reading the logs, I can tell that the problem is in PageBuilder.drawNav(): before it ends, Translator.load() has already started. Can you tell me how to make sure drawNav is fully completed before the code can continue?
Main js
import PageBuilder from "/js/page-builder.js";
import Translator from "/js/translator.js";
var pageBuilder = new PageBuilder();
var translator = new Translator();
pageBuilder.load().then(() => translator.load().then(() => document.getElementById(`languageButton`).onclick = function() {translator.switchLanguage(translator)}));
Translator
/* Courtesy of: https://codeburst.io/translating-your-website-in-pure-javascript-98b9fa4ce427 */
`use strict`
class Translator {
constructor() {
this._lang = this.getLanguage();
this._elements = document.querySelectorAll(`[data-i18n]`);
}
getLanguage() {
var lang = navigator.languages ? navigator.languages[0] : navigator.language;
return lang.substr(0, 2);
}
load(lang = null) {
this._elements = document.querySelectorAll(`[data-i18n]`);
console.log("Translator.load() document.querySelectorAll...");
console.log(this._elements);
if (lang) {
this._lang = lang;
}
else {
var re = new RegExp(`lang=([^;]+)`);
var value = re.exec(document.cookie);
var cookieLang = (value != null) ? unescape(value[1]) : null;
if (cookieLang) {
this._lang = cookieLang;
}
}
return fetch(`/json/lang-${this._lang}.json`)
.then((res) => res.json())
.then((translation) => {
this.translate(translation);
})
.then(this.toggleLangTag())
.then(document.cookie = `lang=${this._lang};path=/`)
.then(() => {
console.log("Translator.load() --end document.querySelectorAll...");
console.log(this._elements);
})
}
translate(translation) {
console.log("translate(translation)");
this._elements.forEach((element) => {
var keys = element.dataset.i18n.split(`.`);
var text = keys.reduce((obj, i) => obj[i], translation);
if (text) {
element.innerHTML = text;
}
else {
element.innerHTML = `key ${keys} not found for ${this._lang}!`
}
});
}
toggleLangTag() {
if (document.documentElement.lang !== this._lang) {
document.documentElement.lang = this._lang;
}
}
switchLanguage(translator) {
var availableLang = [`en`, `fr`];
var currentLangIndex = availableLang.indexOf(translator._lang);
var nextLang = availableLang[(currentLangIndex + 1)%availableLang.length];
translator.load(nextLang);
}
}
export default Translator;
PageBuilder
`use strict`
class PageBuilder {
constructor() {
this._nav = document.getElementsByTagName(`nav`)[0];
this._footer = document.getElementsByTagName(`footer`)[0];
this._url = window.location.href;
}
load() {
return this.drawFooter()
.then(() => fetch(`/json/menu.json`))
.then((res) => res.json())
.then((jsonMenu) => {
this.drawNav(jsonMenu);
})
}
drawFooter() {
console.log("drawFooter()");
return fetch(`/templates/footer.html`)
.then((res) => res.text())
.then((resText) => {
console.log(`this._footer=${this._footer}`);
console.log(`resText=${resText}`);
this._footer.innerHTML = resText;
console.log("drawFooter()--end");
console.log("PageBuilder.drawFooter() document.querySelectorAll...");
console.log(document.querySelectorAll(`[data-i18n]`));
})
}
drawNav(jsonMenu) {
console.log("drawNav(jsonMenu)");
var htmlMenu = ``;
return fetch(`/templates/site-title-div.html`)
.then((res) => res.text())
.then((resText) => {
htmlMenu = resText;
console.log(`htmlMenu=${htmlMenu}`);
})
.then(() => {
htmlMenu += `<ul>`;
var previousParent = `/`;
var ulOpen = false;
for(var i = 0; i < jsonMenu.length; i++) {
var jsonMenuItem = jsonMenu[i];
var regexp = /http:\/\/cypher-f\.com((\/[a-z\-]*)?(\/[a-z\-]+)?)/g;
var match = regexp.exec(this._url);
var currentPageFullUrl = match[0];
var currentPageFullHref = match[1];
var currentPageParent = match[2];
var currentPageLevel2 = match[3];
var openingUl = ``;
var closingUl = ``;
var jsonParent = jsonMenuItem[`parent`];
if ((jsonParent === `/`) || (jsonParent === currentPageParent)) {
if (jsonParent != previousParent) {
if (ulOpen) {
htmlMenu += `</ul>`;
ulOpen = false;
}
if (jsonParent != `/`) {
htmlMenu += `<ul>`;
ulOpen = true;
}
}
var material_icon = jsonMenuItem[`material-icon`];
var href = jsonMenuItem[`href`];
var i18n = jsonMenuItem[`data-i18n`];
var active = (currentPageFullHref === jsonMenuItem.href ? ` class="active"` : ``);
htmlMenu += `<li${active}><i class="material-icons">${material_icon}</i><a href="${href}" data-i18n="${i18n}"></a></li>`;
previousParent = jsonParent;
}
}
if (ulOpen) {
htmlMenu += `</ul>`;
}
htmlMenu += `</ul>`;
this._nav.innerHTML = htmlMenu;
console.log("drawNav(jsonMenu)--end");
console.log("PageBuilder.drawNav() document.querySelectorAll...");
console.log(document.querySelectorAll(`[data-i18n]`));
})
}
}
export default PageBuilder;