Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I am trying to create a simple shopping cart using javascript and prototypes.
Just a simple console app.
I want to call myBasket.prototype.addItems to add items in the inventory[] and similarly I would want to call myBasket.prototype.addQuantity and myBasket.prototype.totalAmount to increase the quantity of an item and sum the total amount respectively.
Where I am stuck is how do I call myBasket.prototype.addItems to do the needful? This is where I am stuck.
var inventory =
[
{ name: "apples", price: 19.95, quantity: 50 },
{ name: "oranges", price: 20.99, quantity: 40 },
{ name: "pineapples", price: 40.00, quantity: 60 },
{ name: "lemons", price: 10.12, quantity: 100 }
]
function myBasket(name, price, quantity){
this.name = name;
this.price = price,
this.quantity = quantity;
items.push(this);
}
myBasket.prototype.addItems = function(){
console.log('items added to cart')
}
myBasket.prototype.addQuantity = function(){
console.log('item quantity added to cart')
}
myBasket.prototype.totalAmount = function(){
console.log('Total amount is');
var total = this.price * this.quantity;
}
// newItem.prototype = Object.create(myBasket.prototype);
var newItem = [];
newItem = new myBasket({name:'milk', price:80,quantity: 2});
newItem.push(this.items);
console.log('new item(s) added', items);
var checkoutAmount = new myBasket();
console.log('checkout amount');
No, since you are new to OOP, think it this way. Every thing is an object.
So in your case, you should have class Item and class Basket you should also have a way to add and remove items from your basket.
See the code snippet bellow
class Item{
constructor(name,price,quantity) {
this.name = name;
this.price = price;
this.quantity = quantity;
}
}
class Basket {
constructor() {
this.items = []
}
addItem(item){
this.items.push(item)
}
}
let items = [
new Item("apples",40,20),
new Item("lemons",32,38),
new Item("mangos",44,67),
new Item("pineapples",32,88)
]
let basket = new Basket()
let market = document.getElementById("market")
let s = items.map((item,id)=>"<button onClick=addItem("+id+")>Add "+item.name+"</button>").join("")
market.innerHTML = s
function addItem(id) {
basket.addItem(items[id])
showBasket()
}
function showBasket() {
let cart = document.getElementById("items")
let s = basket.items.map((item,id)=>"<span style='margin: 5px'>"+item.name+"</span>").join("")
cart.innerHTML = s
}
<fieldset>
<legend>Basket</legend>
<div id="items"></div>
</fieldset>
<div id="market"></div>
Hope that answers your question
Since the question was edited and added to use prototypes, I am going to once more produce an elaboration using function prototypes
function Item(name,price,quantity) {
this.name = name;
this.price = price;
this.quantity = quantity;
}
function Basket() {
this.items = []
}
Basket.prototype.addItem = function(item) {
this.items.push(item);
}
let items = [
new Item("apples",40,20),
new Item("lemons",32,38),
new Item("mangos",44,67),
new Item("pineapples",32,88)
]
let basket = new Basket()
let market = document.getElementById("market")
let s = items.map((item,id)=>"<button onClick=addItem("+id+")>Add "+item.name+"</button>").join("")
market.innerHTML = s
function addItem(id) {
basket.addItem(items[id])
showBasket()
}
function showBasket() {
let cart = document.getElementById("items")
let s = basket.items.map((item,id)=>"<span style='margin: 5px'>"+item.name+"</span>").join("")
cart.innerHTML = s
}
<fieldset>
<legend>Basket</legend>
<div id=items></div>
</fieldset>
<div id=market></div>
To add items to an array, use push():
function myBasket(name, price, quantity){
this.name = name;
this.price = price,
this.quantity = quantity;
items.push(this);
}
Related
I've created a shopping cart, and right now the the cart contains a single apple, a single orange, and the total prices.
How would I add a second "apple" without creating another object?
For example, I now would like to add 2 apples to the cart, so the price in the array gets updated, as well as the total amount.
module.exports = {
shoppingCart: function () {
//create empty cart array
theCart = [];
// create two seperate versions of the same kind of object using class method
class Fruits {
constructor(fruit, price) {
this.fruit = fruit;
this.price = price;
// this.quantity = price * 2;
}
}
let fruit1 = new Fruits('Apple', 4.95); // create new object. sets the value of this
let fruit2 = new Fruits('Orange', 3.99);
let fruit3 = new Fruits('Total amount', fruit1.price + fruit2.price);
// combine both fruits into an array
let bothFruits = [fruit1, fruit2, fruit3];
//add items to the cart
Array.prototype.push.apply(theCart, bothFruits);
//remove items from the cart by calling this function
function removeAllItems() {
if ((theCart.length = !0)) {
theCart = [];
}
}
//removeAllItems();
console.log(theCart);
},
};
You may try to add the quantity also. Please try the following code:
module.exports = {
shoppingCart: function () {
//create empty cart array
theCart = [];
// create two seperate versions of the same kind of object using class method
class Fruits {
constructor(fruit, price, quantity) {
this.fruit = fruit;
this.quantity = quantity;
this.price = price * quantity;
}
}
let fruit1 = new Fruits("Apple", 4.95, 2); // create new object. sets the value of this
let fruit2 = new Fruits("Orange", 3.99, 1);
let fruit3 = new Fruits("Total amount", fruit1.price + fruit2.price);
// combine both fruits into an array
let bothFruits = [fruit1, fruit2, fruit3];
//add items to the cart
Array.prototype.push.apply(theCart, bothFruits);
//remove items from the cart by calling this function
function removeAllItems() {
if (theCart.length = !0) {
theCart = [];
}
}
//removeAllItems();
console.log(theCart);
}
}
You can try this code:
class Fruits {
constructor() {
this.items = [];
this.totals = 0;
}
calculateTotals() {
this.totals = 0;
this.items.forEach(item => {
let price = item.price;
let quantity = item.quantity;
let amount = price * quantity;
this.totals += amount;
});
}
addToCart(fruit, price, quantity) {
let obj = { fruit, price, quantity }
this.items.push(obj);
this.calculateTotals();
}
get cart() {
return { items: this.items, totals: this.totals }
}
}
const fruitsCart = new Fruits();
fruitsCart.addToCart("Apple", 10.5, 2);
fruitsCart.addToCart("Orang", 15, 1);
const cart = fruitsCart.cart;
this now adds the total amount in a separate variable
module.exports = {
shoppingCart: function () {
//create empty cart array
theCart = [];
// create two seperate versions of the same kind of object using class method
class Fruits {
constructor(fruit, price, quantity) {
this.fruit = fruit;
this.quantity = quantity;
this.price = price * quantity;
}
}
let fruit1 = new Fruits("Apple", 4.95, 2); // create new object. sets the value of this
let fruit2 = new Fruits("Orange", 3.99, 1);
//let fruit3 = new Fruits("Total amount", fruit1.price * fruit2.price);
// combine both fruits into an array
let bothFruits = [fruit1, fruit2];
//add items to the cart
Array.prototype.push.apply(theCart, bothFruits);
let total = fruit1.price + fruit2.price;
//remove items from the cart by calling this function
function removeAllItems() {
if (theCart.length = !0) {
theCart = [];
}
}
//removeAllItems();
console.log(theCart, total);
}
}
im still trying to learn and im trying to make a group of actors be added to a movie class, i made it work but i still have problems because if you add another actor the last one dissappears, i tried with a loop but i could do nothing.
class Movie {
constructor(title,year,duration){
this.title = title;
this.year = year;
this.duration = duration;
}
addCast(actors){
this.actors = actors
}
}
class Actor {
constructor(name,age)
{
this.name = name;
this.age = age;
}
}
const terminator = new Movie('Terminator I', 1985, 60);
const arnold = new Actor('Arnold Schwarzenegger', 50);
const otherCast = [
new Actor('Paul Winfield', 50),
new Actor('Michael Biehn', 50),
new Actor('Linda Hamilton', 50)
];
//From here it can not be modified
let movieOne = new Movie("Kong","2018","2h30m");
let movieTwo = new Movie("Joker","2019","2h03m");
let movieThree = new Movie("John Wick 3", "2019", "1h49m");
terminator.addCast(arnold);
terminator.addCast(otherCast);
//To here it can not be modified
console.log({movieOne,movieTwo,movieThree,terminator});
See? Arnold should be in the actors too but it isnt! Thanks for the help in advance.
Another thing, this is for an excercise and i can not modify the lines i commented.
You have
addCast(actors){
this.actors = actors
}
This does not add the passed actor array to the actors on the instance - it replaces the instance's actors with the passed argument. Calling addCast will result in whatever previously existed on actors being lost.
To help reduce bugs, it can help to name methods appropriately - for logic like this, I'd call it setCast, not addCast.
If you want to add onto the end of the existing cast, and you're not sure whether the argument will be a single actor to add or an array of actors to add, use:
addCast(actorOrActors) {
if (Array.isArray(actorOrActors)) {
this.actors.push(...actorOrActors);
} else {
this.actors.push(actorOrActors);
}
}
class Movie {
constructor(title, year, duration) {
this.title = title;
this.year = year;
this.duration = duration;
this.actors = [];
}
addCast(actorOrActors) {
if (Array.isArray(actorOrActors)) {
this.actors.push(...actorOrActors);
} else {
this.actors.push(actorOrActors);
}
}
}
class Actor {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
const terminator = new Movie('Terminator I', 1985, 60);
const arnold = new Actor('Arnold Schwarzenegger', 50);
const otherCast = [
new Actor('Paul Winfield', 50),
new Actor('Michael Biehn', 50),
new Actor('Linda Hamilton', 50)
];
//From here it can not be modified
let movieOne = new Movie("Kong", "2018", "2h30m");
let movieTwo = new Movie("Joker", "2019", "2h03m");
let movieThree = new Movie("John Wick 3", "2019", "1h49m");
terminator.addCast(arnold);
terminator.addCast(otherCast);
//To here it can not be modified
console.log({
movieOne,
movieTwo,
movieThree,
terminator
});
This is because in your addCast() method, each time you call it, you are replacing the previous value instead of appending it
You overwrite arnold with your second addActors call.
Only add one actor at a time to an array of actors.
class Movie {
constructor(title,year,duration){
this.title = title;
this.year = year;
this.duration = duration;
this.actors = [];
}
addCast(actor){
this.actors.push(actor);
}
terminator.addCast(arnold);
terminator.addCast(otherCast[0]);
terminator.addCast(otherCast[1]);
terminator.addCast(otherCast[2]);
I am following a tutorial to build a budget calculation using modules.For one of the function calcTotal in the module budgetController the guy uses the forEach method and I would like to rewrite it as a for loop.
In this function I am trying to calculate the total of all the expenses and income that the user input on the website. The value get passed to the data.object in the budgetController module. I insert different comments in the full code below to make it as easy as possible to understand.
calcTotal = function(type){
var sum = 0;
data.allItems[type].forEach(function(cur){
sum += cur.value;});
data.totals[type] = sum;
}
var data = {
allItems: {
exp: [],
inc: []
},
totals : {
exp: 0,
inc: 0
},
budget: 0,
percentage: -1
};
The code above is working fine but I tried to do the same with for loop and for some reason is not working.
Could anyone rewrite the forEach method in the function calcTotal as a for loop so I can see what I am doing wrong?
here is the full code:
var budgetController = (function(){
var Expense = function(id, description, value){
this.id = id;
this.description = description;
this.value = value;
};
var Income = function(id, description, value){
this.id = id;
this.description = description;
this.value = value;
};
calcTotal = function(type){
var sum = 0;
data.allItems[type].forEach(function(cur){
sum += cur.value;});
data.totals[type] = sum;
}
var data = {
allItems: {
exp: [],
inc: []
},
totals : {
exp: 0,
inc: 0
},
budget: 0,
percentage: -1
};
return{
addItem: function(type, des, val){
var newItem
var ID = 0;
if(data.allItems[type].length > 0 ){
ID = data.allItems[type][data.allItems[type].length - 1].id +1;
}
else{ID = 0};
//create new item based on exp or inc type
if (type === "exp"){
newItem = new Expense(ID, des, val)
}
else if(type === "inc"){
newItem = new Income(ID, des, val);
}
//Push it into our data structure
data.allItems[type].push(newItem);
//returning the new element
return newItem;
},
calculateBudget: function(){
//calculate total income and expenses
calcTotal("exp");
calcTotal("inc");
// calculate the totalBudget
data.budget = data.totals.inc - data.totals.exp;
// calculate the pecentage;
data.percentage = Math.round((data.totals.exp / data.totals.inc) * 100);
},
testing: function(){
console.log(data);
},
getBudget: function(){
return{
budget: data.budget,
expenses: data.totals.exp,
income: data.totals.inc,
percentage: data.percentege
}
}
}
})()
var UIcontroller = (function(){
getDOM = {
inputValue: ".add__value",
inputDescription: ".add__description",
inputType: ".add__type",
addButton: ".add__btn",
expensesList: ".expenses__list",
incomeList: ".income__list"
};
return {
getInput: function(){
return{
value: parseFloat(document.querySelector(getDOM.inputValue).value),
description: document.querySelector(getDOM.inputDescription).value,
type: document.querySelector(getDOM.inputType).value,
};
},
getDomStrings: function(){
return getDOM;
},
displayListItem: function(type, obj){
var html, newHtml, element
if(type === "exp"){
element = getDOM.expensesList;
html = '<div class="item clearfix" id="expense-%id%><div class="item__description">%description%</div><div class="right clearfix"><div class="item__value">%value%</div><div class="item__percentage">21%</div><div class="item__delete"><button class="item__delete--btn"><i class="ion-ios-close-outline"></i></button></div></div></div>';
}
else if(type === "inc"){
element = getDOM.incomeList;
html = '<div class="item clearfix" id="expense%id%"><div class="item__description">%description%</div><div class="right clearfix"><div class="item__value">%value%</div><div class="item__percentage">10%</div><div class="item__delete"><button class="item__delete--btn"><i class="ion-ios-close-outline"></i></button></div></div></div>';
}
newHtml = html.replace("%id%", obj.id);
newHtml = newHtml.replace("%description%", obj.description);
newHtml = newHtml.replace("%value%", obj.value)
document.querySelector(element).insertAdjacentHTML("beforeend", newHtml);
},
clearFields :function(){
var fields, arrayField
fields = document.querySelectorAll(getDOM.inputValue +"," + getDOM.inputDescription);
arrayField = Array.prototype.slice.call(fields);
fields.forEach(function(current, index, array){
current.value = "";
});
arrayField[0].focus();
}
}
})()
var controller = (function(budgetCntrl, cntrlUI){
var updateBudget = function(){
var budget
// Calculate the Budget
var calcBudget = budgetCntrl.calculateBudget();
// Return the Budget
budget = budgetCntrl.getBudget();
console.log(budget);
//Display the Budget in UI
}
var addItem = function(){
var input, newItem, addItems, clearFields
// Get the file input data
input = cntrlUI.getInput();
// add new Item to the budget Controller
newItem;
if(input.description !=="" && !isNaN(input.value) && input.value > 0){
newItem = budgetCntrl.addItem(input.type, input.description, input.value);
// display Items in the user interface
addItems = cntrlUI.displayListItem(input.type, newItem);
// clear Fields
clearFields = cntrlUI.clearFields();
updateBudget();
// calculate the budget
// display Budget in the user interface
}
}
var setupEventListener = function(){
var DOM = cntrlUI.getDomStrings();
document.querySelector(DOM.addButton).addEventListener("click", addItem);
}
return{
init: function(){
console.log("app has started");
setupEventListener();
}
}
})(budgetController, UIcontroller)
controller.init();
I hope I was clear.
This code:
calcTotal = function(type){
var sum = 0;
data.allItems[type].forEach(function(cur){
sum += cur.value;});
data.totals[type] = sum;
}
Could be re-written as:
function calcTotal(type){
var sum = 0;
for (let i = 0; i < data.allItems[type].length; i++) {
sum += data.allItems[type][i].value;
}
data.totals[type] = sum;
}
Full source: https://jsfiddle.net/gpj40raf/2/
However, may I give you some code review advice?
calcTotal depends on data defined in the enclosing environment. This is not a good idea. It will be better to pass data as a parameter (in certain cases using the closure is good, but this is not one of them). One of the bugs that you have in the complete code is that calcTotal depends on values defined bellow. This will work because of JavaScript hoisting, but is not a good practice.
Note that the forEach code depends that each value is in a value property, but the rest of the code is assuming that values are numbers (i.e. calculateBudget).
The calculation of the total could be abstracted easily without depending on a particular data "shape". For example: data.totals['type']=calcTotal(data.allItems['type']). This makes easy to understand what's going on.
Take a look to Array functions map/reduce/filter. What they do is to abstract certain patterns in a way that's more declarative. For example, to sum values you can use: values.reduce((total, value)=>total+value, 0) (in one line you can express the same as calcTotal).
Take a look to the ES6 constructs. All the new browsers support that today, and you'll be able to use const/let, string literals ,and class for Expense and Income.... the code will be shorter and easy to read.
I'm trying to fill an array with new objects, but the only thing I get is - Uncaught TypeError: product is not a constructor
Here's my code for obj. constructor:
function product(id, preview, colors, sizes, title, price) {
this.id = id;
this.preview = preview;
this.colors = colors;
this.sizes = sizes;
this.title = title;
this.price = price;
};
and code for loop:
var products = [];
for( i=0; i<db.length; i++) {
var xyz = db[i];
products[i] = new product( xyz.id, xyz.preview, xyz.colors, xyz.sizes, xyz.title, xyz.price );
};
here's "minfied" code block example:
https://jsfiddle.net/cujrfhyL/1/
-Thanks in advance.
If products array variable already has some kind of data, it's better you use the array push as not to override the data it contains
var product1 = { id: 6566, price: 3 };
var product2 = { id: 6566, price: 3 };
var product3 = { id: 6568, price: 3 };
var db = [ product1, product2 ];
function product(id, price) {
this.id = id;
this.price = price;
};
var products = [new product(product3.id,product3.price)];
function addProducts() {
for( i=0; i<db.length; i++) {
var xyz = db[i];
products.push(new product( xyz.id, xyz.price ));
}
console.log(products)
};
addProducts();
You need to use the new operator.
products[i] = new product( xyz.id, xyz.price );
var product1 = { id: 6566, price: 3 };
var product2 = { id: 6566, price: 3 };
var db = [ product1, product2 ];
function product(id, price) {
this.id = id;
this.price = price;
};
var products = [];
function addProducts() {
for( i=0; i<db.length; i++) {
var xyz = db[i];
products[i] = new product( xyz.id, xyz.price );
alert(products[i]);
}
};
addProducts();
Don't know if you are having your same problem on local, but in your fiddle you misstyped:
Written there:
var product1 = { id: 6566, price: 3 };
var product2 = { id: 6566, price: 3 };
var db = [ product6566, product6646 ];
But you need to reference product1 and product2 in db:
var db = [ product1, product2 ];
Appart from that, you need to use the "new" keyword:
your code:
products[i] = product( xyz.id, xyz.price );
Correct code:
products[i] = new product( xyz.id, xyz.price );
In Updated working fiddle you can see it working perfectly
Converting function list into order so it is OOP.
Currently I've a class shoppingCart functionality.
Inside shoppingCart we have; save, load, remove, etc and than access it.
a) Is this written in OOP correctly
b) How do you access specific functions.
JS
var cart = [];
function shoppingCart() {
//var Item = function(title, description, price, image_url, count) {
this.newitem = function(title, description, price, image_url, count) {
this.title = title
this.description = description
this.price = price
this.image_url = image_url
this.count = count
}
//function addIteamToCart(title, description, price,image_url, count){
this.addNewitem = function addIteamToCart(title, description, price, image_url, count) {
for (var i in cart) {
console.log(cart);
if (cart[i].title === title) {
cart[i].count += count;
return;
}
}
var item = new Item(title, description, price, image_url, count);
console.log(item);
cart.push(item);
saveCart();
}
};
console.log(shoppingCart.newitem(sss,ddd,zzz,sss));
You need to create a ShoppingCart object:
var sc = new shoppingCart();
sc.newitem(sss, ddd, zzz, sss);
console.log(sc);
BTW, the cart variable should probably be local to the shoppingCart function, not a global variable. And then it should be passed as an argument to saveCart().