在异步调用后设置层次结构对象时遇到问题

Trouble with setting up an hierarchy object following asynchronous calls

提问人:Froilán Olesti Casas 提问时间:11/15/2023 更新时间:11/15/2023 访问量:12

问:

我正在尝试从我们存储在数据库中的一些类别创建类别层次结构。问题是我们从不同的表中获取信息:我们有一种方法可以获取与 Categories 相关的所有信息,然后另一种方法是仅使用 parentCategoryId 和 childCategoryId 字段存储 ParentChild 数据,在那里我们可以看到它们之间的关系。

Category 对象中没有与亲属关系相关的信息,因此我尝试使用我们得到的信息来获取。到目前为止,这就是我得到的:

    const categoryMap = {};

    categories.forEach((category) => {
      const id = category.id;

      this.categoryService
        .getParentChildCategories(category.id)
        .subscribe((childCategories) => {
          const isParent = childCategories.length > 0;
          if (isParent) {
            this.secondLevelCategories.push(category);
            childCategories.map((childCategory) => {
              this.categoryService
                .getParentChildCategories(childCategory.id)
                .subscribe((grandchildCategories) => {
                  const isGrandparent = grandchildCategories.length > 0;
                  const childId = childCategory.id;
                  if (isGrandparent) {
                    this.firstLevelCategories.push(category);
                    categoryMap[id] = { ...category, children: [], parentId: null };

                    categoryMap[id].children[childId] = {
                      ...childCategory,
                      children: [],
                      parentId: id,
                    };

                    grandchildCategories.forEach((grandchildCategory) => {
                      categoryMap[category.id].children[childId].children.push(
                        grandchildCategory
                      );
                      grandchildCategory.parentId = childId;
                      this.thirdLevelCategories.push(grandchildCategory)
                    });
                  } else {
                    categoryMap[id] = { ...category, children: [] };
                  }
                });
            });
          } else {
            categoryMap[id] = { ...category, children: [] };
            //this.firstLevelCategories.push(category)
          }
          console.log(categoryMap)
        });
    });

    return categoryMap;
  } 

因此,我们开始将 categories 对象作为参数传递,该参数是从 CategoryService 中获取的,该参数使用 http get 调用来获取所有类别数据。

然后,对于每个类别,我们使用 getParentChildCategories 调用来检查前面提到的第二个表,并获取将类别评估为 parentCategory 的 childCategories 作为响应。

我们创建了一个 categoryMap 对象,以便映射此层次结构并在前端进一步使用它。

对于 childCategories,我们将对它们执行 getParentChild 方法,以检查它们是否再有子类别。如果是这种情况,我们将通过创建 category.id 对象来开始映射,将其子类别和孙子类别推送到相应的 childCategory。

在此之前,一切都很顺利。但是,存在一些异步问题,因为我无法访问最后一个 if 部分之外的 categoryMap 数据,因此我需要操作其中的数据。但我无法弄清楚如何。

目前,我已经能够将子和孙子类别映射到一个确实具有两者的类别,但我还没有弄清楚如何对其余部分进行排序。事实上,孙子类别正在被填充为父类别,以及父类别中的其他子类别也是如此。

我正在分享我得到的对象以供参考:

    "1084": {
        "id": 1084,
        "name": "DummyCorp",
        "description": "Dummy Corporation",
        "color": "#abcdef",
        "hidden": false,
        "isFavorite": false,
        "reportCount": 17,
        "organizationId": "dummy-org-id-123",
        "image": "dummy-image-url",
        "order": 1,
        "parentId": null,
        "children": [
            null,
            null,
            {
                "id": 1087,
                "name": "Tools",
                "description": "Tools",
                "color": "#123456",
                "hidden": false,
                "isFavorite": false,
                "reportCount": 0,
                "organizationId": "dummy-org-id-123",
                "image": "dummy-image-url",
                "order": 1,
                "parentId": 1084,
                "children": [
                    {
                        "id": 1092,
                        "name": "Marketing",
                        "description": "Marketing",
                        "color": "#789012",
                        "hidden": false,
                        "isFavorite": false,
                        "reportCount": 0,
                        "organizationId": "dummy-org-id-123",
                        "image": "dummy-image-url",
                        "order": 1,
                        "parentId": 1087
                    },
                    {
                        "id": 1099,
                        "name": "NuevaCat",
                        "description": "NuevaCat",
                        "color": "#345678",
                        "hidden": false,
                        "isFavorite": false,
                        "reportCount": 0,
                        "organizationId": "dummy-org-id-123",
                        "image": "dummy-image-url",
                        "order": 1,
                        "parentId": 1087
                    },
                    {
                        "id": 1088,
                        "name": "Zebra BI",
                        "description": "Zebra BI",
                        "color": "#901234",
                        "hidden": false,
                        "isFavorite": false,
                        "reportCount": 0,
                        "organizationId": "dummy-org-id-123",
                        "image": "dummy-image-url",
                        "order": 1,
                        "parentId": 1087
                    }
                ]
            }
        ]
    },
    "1085": {
        "id": 1085,
        "name": "Customers",
        "description": "Customers",
        "color": "#fedcba",
        "hidden": false,
        "isFavorite": false,
        "reportCount": 6,
        "organizationId": "dummy-org-id-123",
        "image": "dummy-image-url",
        "order": 1,
        "parentId": 0,
        "children": []
    },
    "1086": {
        "id": 1086,
        "name": "Financial",
        "description": "Financial",
        "color": "#abcdef",
        "hidden": false,
        "isFavorite": false,
        "reportCount": 2,
        "organizationId": "dummy-org-id-123",
        "image": "dummy-image-url",
        "order": 1,
        "parentId": 0,
        "children": []
    },
    "1087": {
        "id": 1087,
        "name": "Tools",
        "description": "Tools",
        "color": "#123456",
        "hidden": false,
        "isFavorite": false,
        "reportCount": 5,
        "organizationId": "dummy-org-id-123",
        "image": "dummy-image-url",
        "order": 1,
        "parentId": 0,
        "children": []
    },
    "1088": {
        "id": 1088,
        "name": "Zebra BI",
        "description": "Zebra BI",
        "color": "#901234",
        "hidden": false,
        "isFavorite": false,
        "reportCount": 3,
        "organizationId": "dummy-org-id-123",
        "image": "dummy-image-url",
        "order": 1,
        "parentId": 0,
        "children": []
    },
    "1092": {
        "id": 1092,
        "name": "Marketing",
        "description": "Marketing",
        "color": "#789012",
        "hidden": false,
        "isFavorite": false,
        "reportCount": 0,
        "organizationId": "dummy-org-id-123",
        "image": "dummy-image-url",
        "order": 1,
        "parentId": 0,
        "children": []
    },
    "1096": {
        "id": 1096,
        "name": "Paginated ",
        "description": "Paginated ",
        "color": "#abcdef",
        "hidden": false,
        "isFavorite": false,
        "reportCount": 5,
        "organizationId": "dummy-org-id-123",
        "image": "dummy-image-url",
        "order": 1,
        "parentId": 0,
        "children": []
    },
    "1097": {
        "id": 1097,
        "name": "Enric Category",
        "description": "Enric Category",
        "color": "#fedcba",
        "hidden": false,
        "isFavorite": false,
        "reportCount": 1,
        "organizationId": "dummy-org-id-123",
        "image": "dummy-image-url",
        "order": 1,
        "parentId": 0,
        "children": []
    },
    "1098": {
        "id": 1098,
        "name": "Mapa",
        "description": "Nueva cat",
        "color": "#abcdef",
        "hidden": false,
        "isFavorite": false,
        "reportCount": 0,
        "organizationId": "dummy-org-id-123",
        "image": "dummy-image-url",
        "order": 1,
        "parentId": 0,
        "children": []
    },
    "1099": {
        "id": 1099,
        "name": "NuevaCat",
        "description": "NuevaCat",
        "color": "#345678",
        "hidden": false,
        "isFavorite": false,
        "reportCount": 1,
        "organizationId": "dummy-org-id-123",
        "image": "dummy-image-url",
        "order": 1,
        "parentId": 0,
        "children": []
    },
    "1100": {
        "id": 1100,
        "name": "Test Category",
        "description": "Test",
        "color": "#abcdef",
        "hidden": false,
        "isFavorite": false,
        "reportCount": 0,
        "organizationId": "dummy-org-id-123",
        "image": "dummy-image-url",
        "order": 1,
        "parentId": 0,
        "children": []
    }
}

所以,我没有想法了。是否有人可以提供有关使用异步数据和对象映射的一些见解?

我已经尝试过 ChatGPT 3,5,但它毫无头绪。

我尝试了一切,但找不到方法。我知道修改类别的表格会更简单,但想尝试用更少的资源来做到这一点。

Angular TypeScript 对象 数据分层 聚类

评论


答:

0赞 Ale_Bianco 11/15/2023 #1

您可以使用异步编程,特别是 Promise 和 .async/await

async function processCategories(categories) {
  const categoryMap = {};

  for (const category of categories) {
    const id = category.id;
    const childCategories = await this.categoryService.getParentChildCategories(category.id);

    if (childCategories.length > 0) {
      this.secondLevelCategories.push(category);

      categoryMap[id] = { ...category, children: [], parentId: null };

      for (const childCategory of childCategories) {
        const grandchildCategories = await this.categoryService.getParentChildCategories(childCategory.id);

        if (grandchildCategories.length > 0) {
          this.firstLevelCategories.push(category);

          const childId = childCategory.id;
          categoryMap[id].children[childId] = {
            ...childCategory,
            children: [],
            parentId: id,
          };

          for (const grandchildCategory of grandchildCategories) {
            categoryMap[id].children[childId].children.push(grandchildCategory);
            grandchildCategory.parentId = childId;
            this.thirdLevelCategories.push(grandchildCategory);
          }
        } else {
          categoryMap[id].children[childCategory.id] = {
            ...childCategory,
            children: [],
            parentId: id,
          };
        }
      }
    } else {
      categoryMap[id] = { ...category, children: [] };
    }
  }

  return categoryMap;
}

// Call the function with your categories array
processCategories(yourCategoriesArray).then(categoryMap => {
  console.log(categoryMap);
});