Patriot
Patriot

Reputation: 312

Angular array.push() returns empty object

hi I am working on a tutorial project, for the first part I am trying to make a form that will accept a book ISBN number and then query it's price on the internet.

As a starter I made an array of books as sample data, a table to display them and a form to accept the ISBN.

At this stage I would just like the form to add the ISBN to the existing array but this is not working. When I submit the form the data is not added to the table but an empty table row is added. So something is happening but somehow not correctly

My appfile

(function() {
var app = angular.module('booksApp', []);

app.controller('BooksController', function() {
    this.queryResults = results;

    });

app.controller('QueryController', function() {
     this.queryBook = function(){
         this.val = this.isbn;
         results.push([{ISBN: }]);
         this.isbn = '';
    };
    });


var results = [
        {
            name: 'book 1',
            ISBN: 1234,
            price: 13.4
        },
        {
            name: 'book 2',
            ISBN: 1234234,
            price: 32.8
        }
    ];


})();

My html file

<body ng-controller="BooksController as books">
    <form ng-controller="QueryController as qry" ng-submit="qry.queryBook()">
        Please enter ISBN number to be queried:
        <input type="text" ng-model="qry.isbn" />
        <input type="submit" value="query" /> <br />
        The queried value is {{qry.val}} 
    </form>

    <table class="table">
        <thead>
            <tr>
                <td>ISBN</td>
                <td>Book Name</td>
                <td>Shop</td>
                <td>Stock</td>
                <td>Price</td>
            </tr>
        </thead>
        <tbody>
            <tr ng-repeat="result in books.queryResults">
                <td>{{result.ISBN}}</td>
                <td>{{result.name}}</td>
                <td>{{result.shop}}</td>
                <td>{{result.stock}}</td>
                <td>{{result.price | currency}}</td>
            </tr>
        </tbody>
    </table>
    <script src="js/angular.js" type="text/javascript"></script>
    <script src="booksApp.js" type="text/javascript"></script>
</body>

Upvotes: 0

Views: 3301

Answers (2)

Gabs00
Gabs00

Reputation: 1877

Rasalom's solution is essentially right but the reason why is not included.

In your HTML you are accessing your results values for display using the below.

        <tr ng-repeat="result in books.queryResults">
            <td>{{result.ISBN}}</td>
            <td>{{result.name}}</td>
            <td>{{result.shop}}</td>
            <td>{{result.stock}}</td>
            <td>{{result.price | currency}}</td>
        </tr>

So you are setting the expectation that each element in the array queryResults is an object. Each of these objects should have the properties ISBN name shop stock price.

When you add a new value to results, you use

results.push([{ISBN: this.val }]);

So you are pushing an array into results. The array has one element, an object with property ISBN.

This causes the issue because you are expecting every element in queryResults to be an object.

When ng-repeat gets to the element that is an array, all of the expected properties are undefined. With angular it appears that trying to interpolate an undefined value using {{}} won't display any value.

See fiddle: http://jsfiddle.net/gabs00/e5jo7sf3/2/

To summarize:

You are adding incorrectly formatted data to the results array. The values are not being printed because you are not passing the data in the expected format. Your code is checking for properties on an array, properties that have not been defined.

results.push({ISBN:this.val});

Adds to queryResults an object as expected, with at least 1 of the expected properties.

Upvotes: 0

Rasalom
Rasalom

Reputation: 3111

Instead of results.push([{ISBN: }]); you need to do: results.push({ISBN: }); because you need to push new object, and results.push([{ISBN: }]); pushed new array with one element.

Upvotes: 1

Related Questions