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 asname
,price
, andquantity
in stock. Include a constructor that initializes these properties. - Add a method
getInfo()
(ortoString()
) toProduct
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
orElectronicProduct
) that extendsProduct
. This subclass should add at least one extra property, such asexpirationDate
for perishable goods (orauthor
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 likeisExpired()
for PerishableProduct that uses the current date to determine if the item is past expiration (you can use theDate
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:
(You can include some objects that represent perishable items with expiration dates, and some that are non-perishable.)
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 } ];
- 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 (usesetTimeout
) with the JSON string or the parsed object data. This represents an async data fetch. - Use
await loadInventory()
(inside anasync
function) or.then()
on it to get the data when it’s “loaded”. Then, parse the JSON (if you received a string) withJSON.parse()
to get an array of product data objects. - Create instances of your
Product
orPerishableProduct
classes from this data. For each object in the array, determine if it should be aProduct
or aPerishableProduct
(perhaps by the presence of anexpirationDate
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 thei
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 useMath.round()
ortoFixed
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, usesetTimeout
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()
orawait
to call this function and then log the updated product info. For instance:If usingrestockProduct("Milk", 5).then(updatedProduct => { console.log(`Restocked ${updatedProduct.name}, new quantity: ${updatedProduct.quantity}`); });
async/await
, you’d dotry { 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’sgetInfo()
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
Criteria | Points |
---|---|
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
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.