I'm encountering a problem with my tree data structure in TypeScript. When I execute the updateInputArray(chatTree);
function, I receive an “invalid array length” error at the line totalArray.push(iteratorNode.data);
. Additionally, the browser freezes when I attempt to log within the returnStringArray()
function, suggesting a potential infinite loop.
The tree appears to be structured correctly initially, as verified by a printTree function. However, the issue arises when the tree is traversed via priority nodes.
Tree creating function:
async function addChatData() {
if (Params && chatId) {
try {
const messages = (await fetchChatData({
userId: 'not important',
chatId: chatId,
getAll: false,
})) as string[];
//console.log(messages);
let i: number = 0;
let k: number = 0;
const temp: TreeNode[] = [];
for (const message of messages) {
i = 0;
try {
const versions = (await fetchChatData({
userId: 'not important',
chatId: 'not important',
messageId: message,
getAll: false,
})) as string[];
const messageNode = new TreeNode(' ', message);
chatTree.children.push(messageNode);
for (const version of versions) {
try {
const versionOfMessage = (await fetchChatData({
userId: 'not important',
chatId: 'not important',
messageId: 'not important',
versionOfMessageId: version,
getAll: true,
})) as VersionOfMessage;
//console.log('Version data: ', versionOfMessage);
const data: string = versionOfMessage.content;
const newNode = new TreeNode(data, message);
// Add the new node as a child to the message node
messageNode.addChild(newNode);
if (i === 0) temp.push(newNode); //store priority child of node
i++;
} catch (error) {
console.error(
'Could not get version of message object ',
error,
);
}
}
//messageNode.priorityChild = 0;
if (k > 0) {
//add message node to previous child to let all priority children be accessed via the returnStringArray fcn.
temp[k - 1].addChild(chatTree.children[k]);
//temp[k - 1].priorityChild = 0;
//console.log(temp);
}
k++;
} catch (error) {
console.error('Could not get version list: ', error);
}
}
} catch (error) {
console.error('Could not get message list: ', error);
}
}
updateInputArray(chatTree);
//console.log(chatTree.printTree());
}
main function of updateInputArray function:
returnStringArray(): string[] {
let iteratorNode: TreeNode = this.children[this.priorityChild];
const totalArray: string[] = [];
while (iteratorNode) {
// If the node's data is not just a space, add it to the totalArray (i.e., skip messageNode data).
//console.log(iteratorNode);
if (iteratorNode.data.trim() !== '') {
totalArray.push(iteratorNode.data);
}
// Proceed to the priority child if it exists, or break the loop
if (iteratorNode.children.length > 0) {
iteratorNode = iteratorNode.children[iteratorNode.priorityChild];
} else {
break; // No more children, so we break the loop
}
}
return totalArray;
}
I am completely stumped on what the issue is, so any help or future debugging steps would be greatly appreciated.
If you have messages without versions, then your code will create cycles in your "tree":
Imagine a minimal example to produce a cycle:
After the first iteration of the outer loop, chatTree
has one child, i.e. node "A", and temp
is empty (because there are no "versions"). k
is set to 1.
In the second iteration of the outer loop, just after the inner loop has finished, chatTree
has two children (one for "A", one for "B"), and temp
has the first (and only) "version" node for "B".
As now k
is greater than zero, the following link is made:
From the node in temp
(a child of "B") to ... node "B"!! This creates a cycle.
And so your returnStringArray
will get into an "infinite" loop and after 32K iterations, the array totalArray
has reached the maximum length possible, leading to the error you got.
Conclusion: the logic of interlinking nodes is wrong. You'll have to revamp that. Without knowing the rest of your code, I can only sketch what could be a solution. I'd suggest dropping the variables i
, k
and temp
, and instead use prevChild
, like so:
let prevChild = null; // TreeNode
for (const message of messages) {
// ...
const messageNode = new TreeNode(' ', message);
// ...
for (const version of versions) {
//...
}
if (messageNode.children.length) {
if (prevChild) {
prevChild.addChild(messageNode); // This sets the link
}
prevChild = messageNode.children[0];
}
}