2

If you have a couple of list items, this list items are returned as individual objects with their tokens/content. So you can essentially have <li>content</li> each with its own parent <ul>.

I believe the way the should be returned is multiple bulleted_list_item in a single bulleted_list_items. That way one can have <ul>{bulleted_list_item}</ul>

Has anyone also come across this issue? How did you solve for it by rendering the ul and li tags?

2 Answers2

1

I'm sure this could be more elegant, but it works:

$listItemCount = 0;
$newBlockArray = [];

foreach ($blocks as $index => &$block) {
    // Check if block is type of 'bulleted_list_item'
    if ($block['type'] === 'bulleted_list_item') {

        // Get previous and next blocks
        $prev = $blocks[$index-1] ?? null;
        $next = $blocks[$index+1] ?? null;

        // Check if current block is the first of a bulleted list
        if ($next && $next['type'] === 'bulleted_list_item' && $prev['type'] !== 'bulleted_list_item' || !$prev) {
            // Add block to list_items in newly created array
            $newBlockArray['blocks'][$index]['list_items'][] = $block;
            $listItemCount++;
        }

        // Check if current block is in a bulleted list
        if ($next && $prev && $next['type'] === 'bulleted_list_item' && $prev['type'] === 'bulleted_list_item') {
            // Add block to list_items of previously created list_items
            $newBlockArray['blocks'][$index - $listItemCount]['list_items'][] = $block;
            $listItemCount++;
        }

        // Check if current block is last of a bulleted list
        if (!$next || $next && $prev && $next['type'] !== 'bulleted_list_item' && $prev['type'] === 'bulleted_list_item') {
            // Add block to list_items of previously created list_items
            $newBlockArray['blocks'][$index - $listItemCount]['list_items'][] = $block;
            // Reset counter
            $listItemCount = 0;
        }
        continue;
    }
    // Do something else with other block types …
}
0

I hit this issue yesterday while building a blog with Notion and solved it by creating a function that uses a while loop to iterate through the 'results' array that is returned from notion API:

const replaceBulletedListsItems = async (blocks) => {
  let i = 0;
  while (i < results.length) {
    if (blocks[i].type === 'bulleted_list_item') {
      let j = i + 1;
      while (
        j < results.length &&
        blocks[j].type === 'bulleted_list_item'
      ) {
        j++;
      }

      const bulletedListItems = blocks.slice(i, j);
      blocks.splice(i, j - i, {
        type: 'bulleted_list',
        bulleted_list: { children: bulletedListItems },
      });
    } else {
      i++;
    }
  }
  return blocks;
};

const blocks = await replaceBulletedListsItems(results);

The function replaces each group of 'bullet_list_item' with a custom object/block with a type of 'bullet_list'. Now when you render code hits the 'bullet_list' block you wrap the block's children with a ul tag.