Search code examples
javascriptes6-promise

Javascript template literals - retrieve subcollection sets


I have data I need to integrate in a string using Template literals. I'm managining to do it except for when the data is of the type Collection.set.

My data is made of a table called Company with multiple records. I need to loop inside it to retrieve the data for each company( this bit is OK and already works), but then inside each company one of the attribute/column called company_tags is of type Collection.set So i need to loop (sort of loop inside the loop) to retrieve the data in order to inject it inside a Template literal, and this part I am failing to do it.

Javascript code

var html = "";
result.forEach(function(msg) {       
  console.log(msg);
  console.log(msg.company_tags);           
  msg.company_tags.forEach(function(value) {
    console.log(value);
  });

  html += `
    <tr id="company-1234" data-id="1234">
            <td class="name">              
                <h2>This is the company name ${msg.company_name}</h2> for which they agree to send an email to ${msg.company_email}
            <td class="location">              
               <h3> ${msg.company_location_city}</h3>
            </td>
            <td class="tags">              
                <h2>yhis is one of the company tags: <b>${msg.company_tags[i]} </b> and it looks nice</h2>          
            </td>
          </tr>  
        `;

      });
      document.getElementById("target").innerHTML = html;

Of course above the part <h2>This are the company tags: ${msg.company_tags[i]} does not work.

I made several attempts I show further below at reaching this Collection set but failed.

The global data called "msg" in the code above comes from a third party. To show you the structure of the data I need to parse/loop/retrieve look like here are the results of the console.log you see on the code above:

The data is the following: this is one of the Company record shown by the console.log in the code above:

console.log(msg) outputs

c {createdAt: Wed Jul 04 2018 16:49:56 GMT+0200 (CEST), updatedAt: Mon Jul 09 2018 15:26:25 GMT+0200 (CEST), _metadata: d}
company_email: "[email protected]"
company_name: "example name"  
company_location : "Dublin" 
company_tags: Set(3)
updatedAt: and so on...
d {_isLocked: false, _readyPromise: Promise, _deferred: null, _root: c, _state: 0, …}

console.log(msg.company_tags) outputs something I am not sure to fully understand. Seems like what is called Collection set.

Set(3) {"tag1", "improvement", "sexy"}
size : 3
__persistedSize__ : 3
__persistedState__: 
{tag1: "tag1", improvement: "improvement", sexy: "sexy"}
__proto__ : Set
[[Entries]] : Array(3)
  > 0 : "tag1"
  > 1 : "improvement"
  > 2: "sexy"
  length : 3 

Today when I my javascript code (see above) operates, I manage to have in my html the right data shown for the columns of "string "type. So the part below works fine for me:

<h2>This is the company name ${msg.company_name}</h2> for which they agree to send an email to ${msg.company_email}

BUT the part below with the column of type Collection.set does not work and shows "undefined"

<td class="tags">              
                <h2>This is one of the company tags: ${msg.company_tags[i]}            
            </td>

It's like I need to loop again (inside the other loopForEach).

Some attempts that failed:

var html = "";
result.forEach(function(msg) {   
  html += `
    <tr id="company-67851" data-id="67851">
            <td class="name">              
                <h2>This is the company name ${msg.company_name}</h2> for which they agree to send an email to ${msg.company_email}
            <td class="location">              
               <h3> ${msg.company_location_city}</h3>
            </td>
            <td class="tags">              
                <h2>This is one of the company tags:  <b>${ msg.company_tags.forEach(function(value) {                   
                        <h2>value</h2>
                      </div>
                    </a>
                  });
                } </h2> and it looks nice           
            </td>
          </tr>  
        `;

      });
      document.getElementById("target").innerHTML = html;

I also tried

${ msg.company_tags.forEach( (k, v) => `<h2>${v}</h2>`).join(" ")  }

and also

${msg.company_tags.map(company_tag => <h2>This is one of the company tags: ${company_tag}</h2> and it looks nice`).join('')}

but I'm always getting UNDEFINED error or even sometimes Uncaught (in promise): TypeError: .map is not a function

Nothing has been working so far. It's a little over my head as a javascript rookie.

My goals is that for example I see in the html for the example of record I gave above:

<td class="tags">              
  <h2>This is one of the company tags: <b>tag1</b> and it looks nice</h2> 
  <h2>These are the company tags: <b>imrovement</b> and it looks nice</h2> 

  <h2>These are the company tags: <b>sexy</b> and it looks nice</h2>                        
</td>

Solution

  • Seems like you need to convert msg.company_tags set into array:

    var company_tags = []
    msg.company_tags.forEach((k,v) => company_tags.push(v))
    

    Then you should be able to map not forEach over it, as only map returns from function, forEach is used for side effects. Also you can fetch generating of company tags into separate function.

    ${company_tags.map(company_tag => `<h2>This is one of the company tags: ${company_tag}</h2> and it looks nice`).join('')}