fremail / sequelize-nested-set

Library to store and manage nested set trees using Sequelize
MIT License
39 stars 10 forks source link

Wrong parent of item when creating item in next branch #32

Open MurzNN opened 2 years ago

MurzNN commented 2 years ago

As example I'm trying to create Tag nested set with tree structure like this:

Electronics
- TVs
- - Apple
- - Samsung
- Phones
- - Xiaomi

Here is the code:

const { Sequelize, DataTypes, queryInterface } = require("sequelize");
const ns = require('sequelize-nested-set');

(async () => {

  const sequelize = new Sequelize({
    dialect: 'sqlite',
    storage: 'database.sqlite'
  });

  await sequelize.authenticate();

  await sequelize.getQueryInterface().dropAllTables();

  const Tag = ns(sequelize, DataTypes, 'Tag', {
    label: DataTypes.STRING,
  }, {
    tableName: 'tag',
    timestamps: false,
    hasManyRoots: true,
  });

  Tag.sync();

  const printTree = async function (ns) {
    const items = await ns.fetchTree(10);
    let strings = [];
    for (let item of items) {
      // console.log(item)
      let parent = await item.getParent();
      strings.push(("- ".repeat(item.level) + `${item.label} [id ${item.id}, parentId ` + (parent.id || '-') + `]`));
    }
    console.log(strings.join("\n"));
  }

  let tagElectronics = new Tag(); tagElectronics.label = 'Electronics';
  tagElectronics = await Tag.createRoot(tagElectronics);

  let tagPhones = new Tag(); tagPhones.label = 'Phones';
  await tagElectronics.addChild(tagPhones);

  let tagTVs = new Tag(); tagTVs.label = 'TVs';
  await tagElectronics.addChild(tagTVs);

  let tagSamsung = new Tag(); tagSamsung.label = 'Samsung';
  await tagTVs.addChild(tagSamsung);

  let tagApple = new Tag(); tagApple.label = 'Apple';
  await tagTVs.addChild(tagApple);

  let tagXiaomi = new Tag(); tagXiaomi.label = 'Xiaomi';
  await tagPhones.addChild(tagXiaomi);

  await printTree(Tag);
})();

But as result I see that Xiaomi item is placed in wrong parent branch! Here is output:

Electronics [id 1, parentId -]
- TVs [id 3, parentId 1]
- - Xiaomi [id 6, parentId 3]
- - Apple [id 5, parentId 3]
- - Samsung [id 4, parentId 3]
- Phones [id 2, parentId 1]

Can you please describe why this happens? Maybe some code parts are wrong?

fremail commented 2 years ago

@MurzNN the issue is in outdated data. addChild method updates the variable with the child node, but doesn't update other variables. You need to update a variable with a parent node before using it (calling addChild and other methods).

  let tagElectronics = new Tag(); tagElectronics.label = 'Electronics';
  tagElectronics = await Tag.createRoot(tagElectronics);

  let tagPhones = new Tag(); tagPhones.label = 'Phones';
  await tagElectronics.addChild(tagPhones);

  await tagElectronics.reload();
  let tagTVs = new Tag(); tagTVs.label = 'TVs';
  await tagElectronics.addChild(tagTVs);

  let tagSamsung = new Tag(); tagSamsung.label = 'Samsung';
  await tagTVs.addChild(tagSamsung);

  await tagTVs.reload();
  let tagApple = new Tag(); tagApple.label = 'Apple';
  await tagTVs.addChild(tagApple);

  await tagPhones.reload();
  let tagXiaomi = new Tag(); tagXiaomi.label = 'Xiaomi';
  await tagPhones.addChild(tagXiaomi);