0

I want to get two elements from a page and put them into one object

const entryElements = await page.$$('div.kpi-entry');
const contents = await Promise.all(
entryElements.map(async (element) => {
  const kpiValue = await (await element.$('span.text-xl'))?.innerText();
  const kpiName = await (await element.$('eui-base-v0-tooltip'))?.innerText();
  const kpiObject = {kpiValue,kpiName,};
  return kpiObject;
})

kpiObject returns

  { kpiValue: '1', kpiName: 'Critical' },
  { kpiValue: '2', kpiName: 'Major' },
  { kpiValue: '3', kpiName: 'Minor' },
  { kpiValue: '4', kpiName: 'Warning' },
  { kpiValue: '5', kpiName: 'Indeterminate' }

but I expected

{
  Critical: '1',
  Major: '2',
  Minor: '3',
  Warning: '4',
  Indeterminate: '5',
}

What is the best way to do this given this HTML?

<div class="kpi">
  <div>
    <!---->
    <!---->
  </div>
  <!---->
  <div class="kpi-entry">
    <div class="kpi-item kpi-value ">
      <span class="text-xl"><!---->3<!----></span>
      <span class="text-lg text-color-gray"><!----> <!----></span>
      <eui-base-v0-tooltip class="kpi-label text-color-gray" message="Critical" position="bottom" delay="500">
        Critical
      </eui-base-v0-tooltip>
    </div>
  </div>
  <!---->
  <div class="kpi-entry">
    <div class="kpi-item kpi-value ">
      <span class="text-xl"><!---->36<!----></span>
      <span class="text-lg text-color-gray"><!----> <!----></span>
      <eui-base-v0-tooltip class="kpi-label text-color-gray" message="Major" position="bottom" delay="500">
        Major
      </eui-base-v0-tooltip>
    </div>
  </div>
  <!---->
  <div class="kpi-entry">
    <div class="kpi-item kpi-value ">
      <span class="text-xl"><!---->5<!----></span>
      <span class="text-lg text-color-gray"><!----> <!----></span>
      <eui-base-v0-tooltip class="kpi-label text-color-gray" message="Minor" position="bottom" delay="500">
        Minor
      </eui-base-v0-tooltip>
    </div>
  </div>
  <!---->
  <div class="kpi-entry">
    <div class="kpi-item kpi-value ">

      <span class="text-xl"><!---->7<!----></span>
      <span class="text-lg text-color-gray"><!----> <!----></span>
      <eui-base-v0-tooltip class="kpi-label text-color-gray" message="Warning" position="bottom" delay="500">
        Warning
      </eui-base-v0-tooltip>
    </div>
  </div>
  <!---->
  <div class="kpi-entry">
    <div class="kpi-item kpi-value ">

      <span class="text-xl"><!---->0<!----></span>
      <span class="text-lg text-color-gray"><!----> <!----></span>
      <eui-base-v0-tooltip class="kpi-label text-color-gray" message="Indeterminate" position="bottom" delay="500">
        Indeterminate
      </eui-base-v0-tooltip>
    </div>
  </div>
  <!---->
</div>
James Westgate
  • 11,306
  • 8
  • 61
  • 68
ray
  • 3
  • 3

3 Answers3

0

This should work too. No need for promises and awaits here

const contents = [...document.querySelectorAll('div.kpi-entry')].map(element => {
    const kpiValue = element.querySelector('span.text-xl')?.textContent.trim() ?? null;
    const kpiName = element.querySelector('eui-base-v0-tooltip')?.textContent.trim() ?? null;
    return kpiName ? { [kpiName]: kpiValue } : null;
  })
  .filter(item => item); // only needed if the map returns any nulls

console.log(contents)
<div class="kpi">
  <div>
    <!---->
    <!---->
  </div>
  <!---->
  <div class="kpi-entry">
    <div class="kpi-item kpi-value ">

      <span class="text-xl"><!---->3<!----></span>
      <span class="text-lg text-color-gray"><!----> <!----></span>
      <eui-base-v0-tooltip class="kpi-label text-color-gray" message="Critical" position="bottom" delay="500">
        Critical
      </eui-base-v0-tooltip>
    </div>

  </div>
  <!---->
  <div class="kpi-entry">
    <div class="kpi-item kpi-value ">

      <span class="text-xl"><!---->36<!----></span>
      <span class="text-lg text-color-gray"><!----> <!----></span>
      <eui-base-v0-tooltip class="kpi-label text-color-gray" message="Major" position="bottom" delay="500">
        Major
      </eui-base-v0-tooltip>
    </div>

  </div>
  <!---->
  <div class="kpi-entry">
    <div class="kpi-item kpi-value ">

      <span class="text-xl"><!---->5<!----></span>
      <span class="text-lg text-color-gray"><!----> <!----></span>
      <eui-base-v0-tooltip class="kpi-label text-color-gray" message="Minor" position="bottom" delay="500">
        Minor
      </eui-base-v0-tooltip>
    </div>

  </div>
  <!---->
  <div class="kpi-entry">
    <div class="kpi-item kpi-value ">

      <span class="text-xl"><!---->7<!----></span>
      <span class="text-lg text-color-gray"><!----> <!----></span>
      <eui-base-v0-tooltip class="kpi-label text-color-gray" message="Warning" position="bottom" delay="500">
        Warning
      </eui-base-v0-tooltip>
    </div>

  </div>
  <!---->
  <div class="kpi-entry">
    <div class="kpi-item kpi-value ">

      <span class="text-xl"><!---->0<!----></span>
      <span class="text-lg text-color-gray"><!----> <!----></span>
      <eui-base-v0-tooltip class="kpi-label text-color-gray" message="Indeterminate" position="bottom" delay="500">
        Indeterminate
      </eui-base-v0-tooltip>
    </div>

  </div>
  <!---->
</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
-1

Try this, I just modified your code a bit

const entryElements = await page.$$('div.kpi-entry');
const kpiObject = {}; // create empty object
const contents = await Promise.all(
entryElements.map(async (element) => {
  const kpiValue = await (await element.$('span.text-xl'))?.innerText();
  const kpiName = await (await element.$('eui-base-v0-tooltip'))?.innerText();
  return kpiObject[kpiName] = kpiValue; // add value directly to object
})
semperlabs
  • 458
  • 4
  • 7
  • its return array [ '1', '2', '3', '4', '5' ] – ray Mar 16 '22 at 08:51
  • Is this kpiObject? Check this example how to assign values using brackets notation https://jsfiddle.net/3mzyaqeL/ – semperlabs Mar 16 '22 at 09:03
  • not me, your tips very useful, and I used " const kpiObject = [kpiName]: kpiValue; " this way to got I expected, thank you – ray Mar 17 '22 at 05:32
-1

You can use Array.map to transform your array of objects

// Your array
const array = [
  { kpiValue: '1', kpiName: 'Critical' },
  { kpiValue: '2', kpiName: 'Major' },
  { kpiValue: '3', kpiName: 'Minor' },
  { kpiValue: '4', kpiName: 'Warning' },
  { kpiValue: '5', kpiName: 'Indeterminate' }
];

// Transformation
const newArray = array.map(obj => ({ [obj.kpiName]: obj.kpiValue }));

// Test
console.log(newArray);
tarkh
  • 2,424
  • 1
  • 9
  • 12