JavaScript Module Object Cannot be Identified, Resulting in this Error: “TypeError: Cannot read properties of undefined (reading ‘getNodeItem’)”

As a preface for my question, I am very new to JavaScript and come from a strongly-typed language background (e.g. Java and C++). Although I have prior experience with JavaScript, I am not entirely familiar with its underlying mechanisms and struggle to engage with the problems posed by dynamic typing. This has not deterred me from trying very hard to not only appreciate the language, but learn to use it effectively.

With that out of the way, I tried to create a Doubly-Linked List using Node.js as a practice problem; I am quite familiar with the data structure, so I figured this would be a safe starting point for me. I am also trying to only use ES Modules to construct individual Nodes of the Doubly-Linked List. This self-imposed constraint was intended to push me outside of my comfort zone with classes and utilize the most recent JS innovations available.

However, it seems my choice to use ES Modules is not panning out. In summary, the return value of the functions getRightNode() and getLeftNode() do not have a return value that JS can identify properly. I say this because my efforts to call the function getNodeItem() does not work and throws the following error message:

console.log(`right = ${ temp.getNodeItem() }`);
                             ^

TypeError: Cannot read properties of undefined (reading 'getNodeItem')

I believe this problem is a direct result of me creating an object without using a classified type. This assertion could be wrong, but it appears to me that the return values of getLeftNode() and getRightNode() cannot be properly tied back to Node objects created by NodeModuleFactory, hence the program’s inability to call the unknown object’s function and the error is thrown.

My questions are as follows:

  1. Is there a way to fix this and allow the program to call the getNodeItem() function from the returned value of getRightNode() and getLeftNode()?
  2. Am I using ES Modules incorrectly/should I simply be using classes for this?

Any insight about this would be greatly appreciated, as I am unsure how to proceed at this stage and feel as though I am missing something.

// File: NodeModuleFactory.js
"use strict"; // <- Requires us to use the best practices for JavaScript coding.

/**
 * Determines whether the parameter passed into the function is a Node by checking
 * to see if it has certain functions.
 * @param check A variable that we will verify whether it is or is not a Node of some
 * kind.
 * @returns {boolean} Where a false value means the parameter is not a Node, and true
 * means it is a Node.
 */
function isNode (check) {
    return (typeof check === "object" &&
        typeof check.getLeftNode() === "object" &&
        typeof check.getRightNode() === "object" &&
        typeof check.getLeftNode === "function" &&
        typeof check.getRightNode === "function" &&
        typeof check.getNodeItem === "function" &&
        typeof check.setLeftNode === "function" &&
        typeof check.setRightNode === "function");
}

/**
 * Allows for the creation of NodeModule objects.
 * @param leftNode This should either be a NodeModule or undefined and will be treated
 * as the NodeModule to the left of the newly created NodeModule object.
 * @param rightNode This should either be a NodeModule or undefined and will be treated
 * as the NodeModule to the right of the newly created NodeModule object.
 * @param item This is the item being stored within the newly created NodeModule
 * object.
 * @returns {undefined|{getRightNode(): NodeModule, setLeftNode(*): void,
 * getNodeItem(): *, setRightNode(NodeModule): void, getLeftNode(): NodeModule}}
 * A NodeModule object that can be accessed and modified within a doubly-linked
 * list data structure. All NodeModule objects will have an immutable item property.
 */
export function create(leftNode, rightNode, item)
{
    // Check to see if either leftNode or rightNode are actually a NodeModule object
    // or set to undefined. If neither of these are the case, then return undefined.
    if (!(leftNode === undefined || isNode(leftNode)) ||
        !(rightNode === undefined || isNode(rightNode)))
        return undefined;

    // 'Private' data members of the NodeModule object.
    let left = leftNode;
    let right = rightNode;

    return {
        /**
         * Obtains the NodeModule object directly to the left of this NodeModule
         * object.
         * @returns {NodeModule} Should be a NodeModule object.
         */
        getLeftNode() {
            return left;
        },

        /**
         * Obtains the NodeModule object directly to the right of this NodeModule
         * object.
         * @returns {NodeModule} Should be a NodeModule object.
         */
        getRightNode() {
            return right;
        },

        /**
         * Obtains this NodeModule object's item that is contained within.
         * @returns {*} Could be any item stored within the LinkedList structure.
         */
        getNodeItem() {
            return item;
        },

        /**
         * Mutates the left data member if newLeft can be determined to be a
         * NodeModule object or undefined.
         * @param newLeft The object or undefined value that should replace the
         * current left data member.
         * @returns {boolean} True means that the reassignment was successful, while
         * false means that the reassignment was unsuccessful.
         */
        setLeftNode(newLeft) {
            if ((newLeft === undefined || isNode(newLeft))) {
                left = newLeft;
                return true;
            }

            return false;
        },

        /**
         * Mutates the right data member if newLeft can be determined to be a
         * NodeModule object or undefined.
         * @param newRight The object or undefined value that should replace the
         * current right data member.
         * @returns {boolean} True means that the reassignment was successful, while
         * false means that the reassignment was unsuccessful.
         */
        setRightNode(newRight) {
            if ((newRight === undefined || isNode(newRight))) {
                right = newRight;
                return true;
            }

            return false;
        }
    };
}
// File: main.js
"use strict"; // <- requires strict adherence to JavaScript best practices.

import { create as newNode } from "./NodeModuleFactory.js";

let head = newNode(undefined, undefined, 0);
let tail = newNode(head, undefined, 1);
console.log(head.setRightNode(tail));

console.log("head");
console.log(`cur = ${ head.getNodeItem() }`);
console.log(`right = ${ head.getRightNode().getNodeItem() }`);

console.log("ntail");
console.log(`left = ${ tail.getLeftNode().getNodeItem() }`);
console.log(`cur = ${ tail.getNodeItem() }`);

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật