Skip to Content
SBA

JavaScript Essentials 2

Overview and Objectives

In this project, you will create a Inventory Management Application using JavaScript. You will:

  • Integrate knowledge from all four modules to build a practical JavaScript application.
  • Design a program using custom classes and prototype-based features for data modeling.
  • Utilize built-in objects (such as Array, Math, JSON, RegExp) to handle data and computations.
  • Implement asynchronous behavior to simulate data retrieval or long-running operations.
  • Demonstrate the ability to structure code logically for a real-world inspired scenario, preparing for more advanced projects beyond this course.

Tasks and Instructions

You will develop a simple Inventory Management program for a small store. The application will manage products in inventory, including loading initial data, providing search functionality, and performing some analytics. The requirements will ensure you exercise class design, inheritance, data processing, and asynchronous operations.

Imagine you are writing a Node.js script or browser script that will do the following:

  • Define a base class for inventory items (products) and at least one subclass for a specialized category of products.
  • Load or initialize product data (simulate fetching from a database or external source).
  • Allow querying the inventory (e.g., search by product name or filter by category).
  • Calculate summary information (like total value of inventory).
  • Simulate an asynchronous update or fetch operation.
  • Use JSON for data interchange format and possibly RegExp for searching or validating input.

Task 1: Class Design - Product and Subclass

  • Create a class Product with properties such as name, price, and quantity in stock. Include a constructor that initializes these properties.
  • Add a method getInfo() (or toString()) to Product that returns a string describing the product (for example: “Product: <name>, Price: $<price>, Qty: <quantity>”). This will help in displaying product info.
  • Implement a static property or method in Product if appropriate. For instance, you might use a static property to keep track of the total number of products or a static method to format prices. (Optional: You could use a static counter to assign unique IDs to each product as they are created.)
  • Create a subclass PerishableProduct (or another category relevant to you, e.g., BookProduct or ElectronicProduct) that extends Product. This subclass should add at least one extra property, such as expirationDate for perishable goods (or author if it’s a book, etc.).
  • In the subclass constructor, call super(...) to initialize base class properties and then set the extra property.
  • Override or add a method in the subclass. For example, override getInfo() to include the extra property (e.g., include expiration date in the info string). Or add a new method like isExpired() for PerishableProduct that uses the current date to determine if the item is past expiration (you can use the Date object from JS for current date).
  • Outcome: By now you should have at least two classes (Product and one subclass) to represent inventory items.

Task 2: Initial Data Load (Using JSON and Async)

  • Prepare some initial product data in JSON format. You can do this by creating a JSON string or an array of objects in your code. For example:
    const initialData = [ { "name": "Milk", "price": 3.5, "quantity": 10, "expirationDate": "2025-05-01" }, { "name": "Bread", "price": 2.0, "quantity": 20, "expirationDate": "2025-04-15" }, { "name": "Laptop", "price": 1200, "quantity": 5 } ];
    (You can include some objects that represent perishable items with expiration dates, and some that are non-perishable.)
  • Convert this data to a JSON string using JSON.stringify() (if it’s not already a JSON string). In a real scenario, this JSON might come from a file or web response. For this project, you can simulate that by having the JSON string in your code or in a separate file and reading it.
  • Implement an asynchronous function loadInventory() that simulates fetching this data. For instance, loadInventory() can return a Promise that resolves after a short delay (use setTimeout) with the JSON string or the parsed object data. This represents an async data fetch.
  • Use await loadInventory() (inside an async function) or .then() on it to get the data when it’s “loaded”. Then, parse the JSON (if you received a string) with JSON.parse() to get an array of product data objects.
  • Create instances of your Product or PerishableProduct classes from this data. For each object in the array, determine if it should be a Product or a PerishableProduct (perhaps by the presence of an expirationDate field). For example:
    let inventory = []; for (let itemData of dataArray) { if (itemData.expirationDate) { // It's perishable inventory.push(new PerishableProduct(itemData.name, itemData.price, itemData.quantity, itemData.expirationDate)); } else { // It's a normal product inventory.push(new Product(itemData.name, itemData.price, itemData.quantity)); } }
  • After this step, inventory is an array of product instances (some base class, some subclass). Log a message when loading is complete, e.g., "Loaded X products into inventory." (where X is the number of items).

Task 3: Search Functionality (Using RegExp)

  • Implement a function searchInventory(keyword) that takes a string keyword and searches for products whose name matches the keyword (case-insensitive). Use a RegExp to make the search case-insensitive. For example, create a regex with the i flag: new RegExp(keyword, "i"). Test this regex against each product’s name (regex.test(product.name)).
  • The search function should return (or log) the list of products that match, or a message if none found. For instance, if keyword is “lap”, it should match “Laptop” from the example data.
  • Use this function to search for a couple of different substrings and log the results. Make sure to test case insensitivity (e.g., searching “milk” should find “Milk”).
  • Additionally or alternatively, implement a filter by category/type: since you have a subclass for perishable items, you could have a function to list all perishable products in inventory. This can simply filter instanceof PerishableProduct. This is not required, but shows use of class relationships in logic.

Task 4: Inventory Analytics (Using Math and other built-ins)

  • Calculate the total value of the inventory. This means summing up price * quantity for each product. Use a loop or array method to accumulate this. You can use Math.round() or toFixed to round the total to two decimal places for currency formatting.
  • Log the total inventory value, e.g., "Total inventory value: $1234.56".
  • Compute additional stats if you like: e.g., find the most expensive product (by unit price) and the cheapest product. You could use Math.max on a mapped array of prices, or simply iterate and compare. Or find the product with the highest total value (price * quantity). These are optional enhancements but demonstrate using Math and array methods.
  • If you included perishable products with expiration dates, you could also use the Date object to find if any products are expired or about to expire (comparing the expirationDate to the current date). This would use Date parsing (new Date(expirationDate)) and comparisons. Log any expired items. (Optional, for additional practice with Date and logic.)

Task 5: Asynchronous Update Simulation

  • Simulate an asynchronous event, such as restocking a product after a delay or fetching new product info. For example, create a function restockProduct(productName, newQuantity) that returns a Promise. Inside, use setTimeout to simulate a delay (e.g., 2 seconds), then resolve by increasing the quantity of the specified product in the inventory. If the product isn’t found, the promise could reject with an error message.
  • Use .then() or await to call this function and then log the updated product info. For instance:
    restockProduct("Milk", 5).then(updatedProduct => { console.log(`Restocked ${updatedProduct.name}, new quantity: ${updatedProduct.quantity}`); });
    If using async/await, you’d do try { let updated = await restockProduct("Milk", 5); ... }.
  • Ensure that you log something before starting the restock to show that the program continues running, and then log the result after the promise resolves. This shows you handled the async behavior correctly.
  • (If you prefer a different async simulation, you could simulate saving the inventory to a database, or fetching current price updates from a server, etc., as long as it uses a promise or async function.)

Task 6: Program Output

  • Finally, run through a sequence as if you are using the program: After loading data, print all products (you can loop through inventory and output each product’s getInfo() result). Then perform a couple of searches and show results. Then print the total value. Then do an async restock and show the updated result.
  • The output should be a series of console logs that demonstrate each feature working: class instances showing their info, search results, computed totals, and async updates. Use clear messages for each so that someone reading the console output can follow what’s happening (for example, label the sections: “Inventory loaded:”, “Search results for ‘lap’:”, “Total value:”, “Restocking Milk…”).

Submission Criteria

The following should be included within a GitHub repository, and submitted via Canvas:

  • Provide your complete JavaScript project code in a file (for example, inventory.js). The code should include class definitions, data loading, and all functionalities as described. Ensure the code is well-organized (you can divide steps into functions as instructed: e.g., searchInventory function, restockProduct function, etc., and then a section at the bottom that executes those functions to demonstrate the outcomes).
  • Include comments to explain key sections, especially where you implement something from a specific module (e.g., when using RegExp or when doing async operations). This will help the graders see that you intentionally included those features.
  • The code should run without syntax errors. If possible, test it in Node.js or a browser console. If any feature is not fully working, comment it out or add a note, so that the rest of the code can run. It’s better to show partial functionality than none.
  • Make sure the output of the program (from console.log statements) covers the major requirements: listing or describing inventory items, search results, total calculations, and an asynchronous action result. You might include an example of the output as comments at the end of your code (optional, but could be helpful for grading).

Grading Rubric

CriteriaPoints
Class implementation: Product class and subclass are correctly defined with appropriate properties and methods. Inheritance (extends and super) is used properly.15 points
Object creation and usage: Instances of classes are created from initial data. The program correctly distinguishes when to use the subclass vs base class based on data (e.g., presence of extra property). Methods like getInfo() (or equivalent) produce correct outputs for each object.15 points
Built-in objects usage: JSON is used to serialize/deserialize data (initial data is handled via JSON stringify/parse). The Math object or related numeric operations are used for calculations (random, round, max/min, or total value computation).10 points
RegExp search functionality: The program can search/filter the inventory by name using a regular expression (case-insensitive). The search function works correctly, returning matching items.10 points
Static and additional features: Utilized a static property or method in a meaningful way (e.g., counting instances or formatting output). Also, handled any date or string operations if applicable (like checking expiration with Date or similar tasks). (Partial credit if static is defined but not used extensively.)10 points
Asynchronous operation: Implemented a simulated async operation (e.g., restocking or fetching new data) using Promises or async/await. The operation successfully updates or retrieves data after a delay, and the result is handled properly (the inventory is updated or new data is integrated).15 points
Program output and correctness: The overall program executes all required features and logs the outcomes clearly. Inventory data is loaded and shown, search results are displayed, totals are calculated correctly, and the async update reflects in the final output. The code runs without runtime errors and matches the scenario described.15 points
Code quality and documentation: Code is well-structured (e.g., use of functions to encapsulate tasks like search or restock), and comments are included to explain major sections. Variable and function names are meaningful. The submission demonstrates a clear understanding of the concepts by how the code is written (even if not every feature is perfect).10 points

Total Points: 100 points

Note

This project is graded across multiple criteria representing different features. Even if one part of your application is not fully functional, you can receive credit for others. For example, if the async part does not work but everything else does, you will still earn the points for classes, built-in usage, etc. Make sure to attempt each feature and document any known issues in comments to maximize your partial credit.