0

im putting together a shopping basket and firstly im implementing the add items bit.

However for some reason when it pushes the values to the array it is creating 2 objects when it should only be pushing 1 to the array. I can't figure out why! It sends the data fine to the array as one object and then the other object's values are undefined.

JS

//Create object for everything to run in as this reduces namespace problems if I add anything later
var shop = {};

//Items table
shop.output = document.getElementById('output');

//Create array for items to be stored
shop.items = [];

//Constructor for items
shop.addItem = function(title, description, price) {
    'use strict';
    this.title = title;
    this.description = description;
    this.price = price;
    //Adds values from contructor to array
    shop.addToArray(title, description, price)
}

shop.addToArray = function (t,d,p) {
    'use strict';
    var item = {title: t, description: d, price: p};
    shop.items.push(item);
}


shop.addToTable = function() {
    'use strict';
    for (var i = 0; i < shop.items.length; i++){
            shop.output.innerHTML += '<tr><td>' + shop.items[i].title + '</td><td>' + shop.items[i].description + '</td><td>' + shop.items[i].price + '</td><tr>'; 
    }
}

shop.process = function() {
    'use strict';
    var title = document.getElementById('title').value;
    var description = document.getElementById('description').value;
    var price = document.getElementById('price').value;
    //send item to constructor
    var user = new shop.addItem (title, description, price);
    shop.addItem()
    console.log(shop.items);
    shop.addToTable()
}



function init() {
    'use strict';
    //Add event listeners for when user clicks add item
    document.getElementById("addItemBtn").addEventListener("click", shop.process);

} // End of init() function.
//On window load call init function
window.onload = init;

HTML

<html>
<head>
    <meta charset="UTF-8">
    <title>Shopping Basket</title>
</head>
<body>

   <div id="input">
        <form action="#" method="post" id="additem" class="basic-grey">
            <label for="title">
                <span>Title:</span>
                <input type="text" name="title" id="title" required>
            </label>
            <label for="description">
                <span>Name:</span>
                <input type="text" name="description" id="description" required>
            </label>
            <label for="price">
                <span>Price: £</span>
                <input type="text" name="price" id="price" required>
            </label>
            <label for="submit" align="center">
                <input type="button" value="Add Item!" id="addItemBtn" class="btn blue">
            </label>
        </form>
    </div>

    <div id="items" align="center">
        <table id="output" class="table">
            <th>Item</th>
            <th>Description</th>
            <th>Price £</th>
        </table>
    </div>

<script src="js/app.js"></script>
</body>
</html>
1
  • Voting to close as 'Off topic' / 'not reproducible'. Commented Oct 22, 2014 at 14:23

2 Answers 2

3

Here's the problem:

var user = new shop.addItem (title, description, price);
shop.addItem()

This is calling shop.addItem() twice: once as a constructor, with the arguments title, descriptor and price, and a second time as a normal method with no arguments. It's the second call that inserts an empty item (since all the arguments will be undefined).

Sign up to request clarification or add additional context in comments.

5 Comments

Bingo! Thanks alot. Im fairly new to JS and programming so im getting to grips with it. It makes sense now because when I call the new shop.addItem it runs through that function which calls addToArray function. Then with shop.addItem() I was calling that function again but with no parameters... I think that's correct?
i think worth mentioning that the first line has two mistakes : addItem is neither a constructor nor returning a value. Thanks to another mistake in addItem ('shop' is used instead of 'this' at the end of thisd method), the item is added to 'shop', but title, description, price, are set on a new Object that is discarded. Code soup.
pastebin.com/27BPu9aH Would this be a better way rather than having another function just to add to the array? @GameAlchemist
@Adam91Holt: That should work, but it would behave exactly the same as your current code. The bug is not in shop.addItem() (although, honestly, I'm not sure what you're trying to do there with those this.title = title assignments), but in shop.process().
Since you are using a 'constructor for items', then you should have an Item Class (function), that's the first thing to do. Then have shop as an instance of a Shop Class, and keep things simple.
1

Have a look at your shop.process() function.

You add the first (good) item with the line

var user = new shop.addItem (title, description, price);

Then you add an undefined item with the line

shop.addItem()

Without testing you code I believe that

var user = new shop.addItem (title, description, price);

does not return a new object at all but just calls the addItem method.

2 Comments

I guess I was 2 mins too slow ;)
Each call to the function with new returns an object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.