0

I am combining 2 concepts of XHR get (which fetches JSON URL from an attribute in web component) and displaying the JSON data as a list. All that is working fine.

But when I want to toggle the list on / off, somehow the query selector All doesnt work. but it does work in browser console.

Maybe because in connected callback, the DOM hasnt been rendered, hence it cannot be edited ? I have tried rendered Callback / render / set timeout but nothing works. Also tried 2 connectedCallback functions, but query selector still doesnt detect the JSON list.

In browser console, document.querySelectorAll('.history-list') works fine. What should I do to make it work. Many thanks.

Here is the code :

connectedCallback(){
 
 
    let lock_time_ul = document.querySelector('#lock-time-ul');
 
    // fetch data from JSON file (WORKING)
      // fetch JSON URL value (ONLY if attribute has been set)
    if (this.hasAttribute('json-url')) 
    {
      this.json_url = this.getAttribute('json-url');
 
      // fetch data from this URL
      const xhr = new XMLHttpRequest();
 
      xhr.open('GET', this.json_url);
 
      xhr.onload = function(){
 
        this.json_output = JSON.parse(xhr.response);
        
        // (WORKING FINE)
        this.json_output.forEach(el => {
 
          // change el.type from enrollment -> locked and cancellation -> unlocked
          if (el.type == "enrollment") 
          {
            el.type = "Locked";
          }
          else if(el.type == "cancellation")
          {
            el.type = "Unlocked";
          } 
 
          var li = document.createElement('li');
 
          var span = document.createElement('span');
 
          span.className = "date";
 
          li.className = "history-list";
 
          span.appendChild(document.createTextNode(el.date));
 
          var div_lock_wrapper = document.createElement('div');
 
          div_lock_wrapper.className = "lock-wrapper";
 
          div_lock_wrapper.style.fontWeight = 500; 
 
          div_lock_wrapper.appendChild(document.createTextNode(el.type));
 
          li.appendChild(span);
 
          li.appendChild(div_lock_wrapper);
 
          lock_time_ul.appendChild(li);
 
        })
 
      }
 
      xhr.send();
    }
  
    // javascript for sidebar show / hide (NOT WORKING, QUERY SELECTOR ALL history-list SHOWS NULL)
    let toggle_lock_history_btn = document.querySelector(".history-title");
    let toggle_lock_history_list = document.querySelectorAll(".history-list");
    let toggle_show_all_text = document.querySelector(".show-all");
  
 
    toggle_lock_history_btn.addEventListener('click', function()
    {
 
      // check the history-title first
      if (toggle_lock_history_btn.textContent == "Hide lock history") 
      {
 
        // toggle off
        toggle_lock_history_list.forEach(el => {
 
          el.style.display = "none";
        })
 
        // hide show-all
        toggle_show_all_text.style.display = "none";
 
        // change Hide to Show in history-title
        toggle_lock_history_btn.textContent = "Show lock history";
 
 
      }
      else if (toggle_lock_history_btn.textContent == "Show lock history")
      {
 
        // toggle on
        toggle_lock_history_list.forEach(el => {
 
          el.style.display = "";
        })
 
        // show show-all
        toggle_show_all_text.style.display = "";
 
        // change Show to Hide in history-title
        toggle_lock_history_btn.textContent = "Hide lock history";
      }
      
    })
 
} // connectedCallback ENDS

My HTML

<test json-url="data.json"></test>
  • can you show your html(markup)? – Gulshan Aggarwal Jan 15 '22 at 06:37
  • just updated the HTML. Its only the custom element. I am not using any shadow dom. all the custom HTML is in constructor > document.body.innerHTML – Tom Cruise Jan 15 '22 at 06:47
  • 1
    ```` can never be a Custom Element; they require a hyphen in the name. Post your full component code, and (a snippet of) your JSON file. PS. ``xhr`` is almost older than I am; see ``fetch``. And use (modern) ``append`` to replace all those ``appendChild``s. – Danny '365CSI' Engelman Jan 15 '22 at 11:04
  • Thanks Danny for reply. Yes, it has a hyphen in between. https://stackoverflow.com/questions/8739605/getelementbyid-returns-null My query got resolved, since the element I was trying to ID was created dynamically. So using window.onload = init; function init(){ my code here } Thanks for your time and efforts – Tom Cruise Jan 15 '22 at 12:12

1 Answers1

0

Got the solution :

window.onload = init;

 function init(){
   // the code to be called when the dom has loaded
 }

since the element I was trying to get by ID was created dynamically (loaded by ajax and created by script).