Noxious Reptile
Noxious Reptile

Reputation: 863

Dropdownlist not updating in knockoutjs

In my knockout binded view even if the values binded to the dropdownlist changes still the dropdownlist is not updated. But if I refresh the page dropdownlist is updated. Everything is working fine. Data is updating in database also. But this binding is not working as expected. Dont know where I went wrong. Tried many things but nothing worked.

Here is my script file:

var ViewModel = function () {
    var gamesUri = '/api/games/';
    var developersUri = '/api/developers/';

    var self = this;
    self.games = ko.observableArray();
    self.error = ko.observable();
    self.detail = ko.observable();
    self.developers = ko.observable();
    self.newGame = {
        Developer: ko.observable(),
        Title:ko.observable(),
        Genre:ko.observable(),
        Year:ko.observable(),
        Price:ko.observable()
    };
    self.newDeveloper = {
        Name: ko.observable()
    };

    self.addDeveloper = function (formElement) {
        var developer = {
            Name:self.newDeveloper.Name()
        };
        ajaxHelper(developersUri, 'POST', developer).done(function (item) {
            self.developers.push(item);
        });
    }

    self.addGame = function (formElement) {
        var game = {
            DeveloperId: self.newGame.Developer().Id,
            Title: self.newGame.Title(),
            Genre: self.newGame.Genre(),
            Year: self.newGame.Year(),
            Price: self.newGame.Price()
        };
        ajaxHelper(gamesUri,'POST',game).done(function(item) {
            self.games.push(item);
        });
    }

    function getDevelopers() {
        ajaxHelper(developersUri, 'GET').done(function (data) {
            self.developers(data);
            console.log('developers' + data);
        });
    }

    getDevelopers();

    self.getGameDetail = function (item) {
        ajaxHelper(gamesUri + item.Id,'GET').done(function(data) {
            self.detail(data);
        });

    };

    function ajaxHelper(uri, method, data) {
        self.error('');
        return $.ajax({
            type: method,
            url: uri,
            dataType: 'json',
            contentType: 'application/json',
            data: data ? JSON.stringify(data) : null
        }).fail(function (jqXHR, textStatus, errorThrown) {
            self.error(errorThrown);
        });
    }

    function getAllGames() {
        ajaxHelper(gamesUri, 'GET').done(function (data) {
            self.games(data);
        });
    }

    getAllGames();
};

ko.applyBindings(new ViewModel());

Here is my view:

<div class="page-header">
    <h1>Game Shop</h1>
</div>

<div class="row">
    <div class="col-md-4">
    <div class="panel panel-default">
        <div class="panel-heading">
            <h2 class="panel-title">Games</h2>
        </div>
        <div class="panel-body">
            <ul class="list-unstyled" data-bind="foreach: games">
                <li>
                    <strong><span data-bind="text: DeveloperName"></span>:<span data-bind="text: Title"></span></strong>
                    <small><a href="#" data-bind="click: $parent.getGameDetail">Details</a></small>
                </li>
            </ul>
        </div>
    </div>
        <div class="alert alert-danger" data-bind="visible: error"><p data-bind="text: error"></p></div>
    </div>
            <div class="col-md-4">
        <div class="panel panel-default">
            <div class="panel-heading"><h2 class="panel-title">Details</h2></div>
            <table class="table" data-bind="with: detail">
                <tr><td>Developer:</td><td data-bind="text: DeveloperName"></td></tr>
                <tr><td>Title:</td><td data-bind="text: Title"></td></tr>
                <tr><td>Price:</td><td data-bind="text: Price"></td></tr>
                <tr><td>Genre:</td><td data-bind="text: Genre"></td></tr>
                <tr><td>Year:</td><td data-bind="text: Year"></td></tr>
            </table>
        </div>
    </div>
        <div class="col-md-4">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h2 class="panel-title">Add Game</h2>
            </div>
                <div class="panel-body">
                <form class="form-horizontal" data-bind="submit: addGame">
                    <div class="form-group">
                        <label for="inputDeveloper" class="col-sm-2 control-label">Author</label>
                        <div class="col-sm-10">
                            <select data-bind="options:developers, optionsText: 'Name', value: newGame.Developer"></select>
                        </div>
                    </div>
                        <div class="form-group" data-bind="with: newGame">
                        <label for="inputTitle" class="col-sm-2 control-label">Title</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" id="inputTitle" data-bind="value:Title" />
                        </div>
                            <label for="inputYear" class="col-sm-2 control-label">Year</label>
                        <div class="col-sm-10">
                            <input type="number" class="form-control" id="inputYear" data-bind="value:Year" />
                        </div>
                            <label for="inputGenre" class="col-sm-2 control-label">Genre</label>
                        <div class="col-sm-10">
                            <input type="text" class="form-control" id="inputGenre" data-bind="value:Genre" />
                        </div>
                            <label for="inputPrice" class="col-sm-2 control-label">Price</label>
                        <div class="col-sm-10">
                            <input type="number" step="any" class="form-control" id="inputPrice" data-bind="value:Price" />
                        </div>
                    </div>
                    <button type="submit" class="btn btn-default">Submit</button>
                </form>
            </div>
        </div>
    </div>
        <div class="row">
        <div class="col-md-4 col-md-offset-4">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <h2 class="panel-title">Add Developer</h2>
                </div>
                    <div class="panel-body">
                    <form class="form-horizontal" data-bind="submit: addDeveloper">

                        <div class="form-group" data-bind="with: newDeveloper">
                            <label for="inputName" class="col-sm-2 control-label">Name</label>
                            <div class="col-sm-10">
                                <input type="text" class="form-control" id="inputName" data-bind="value:Name" />
                            </div>
                        </div>
                        <button type="submit" class="btn btn-default">Submit</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

Upvotes: 1

Views: 56

Answers (1)

JotaBe
JotaBe

Reputation: 39025

That's simply because developers must be an observableArray, instead of an observable. An observable array is an array implementation which is able to notify when elements are added or removed from it. A common observable doesn't do that.

Upvotes: 1

Related Questions