0

I have an HTML file which displays 2 lists using AngularJS file with 2 controllers and a service. The lists are arrays which are being correctly updated in the model, as evidenced by the console.log output. But the HTML doesn't display the updated list2 (data stored in the angularJS service). Can someone tell where I am going wrong?

Tried looking at the API, angular directives, Controller As syntax and inheritance concepts.

index.html

<!DOCTYPE html>
<html lang="en" ng-app="ShoppingListCheckOff">
  <head>
    <title>Shopping List Check Off</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" href="styles/bootstrap.min.css" />
    <script src="angular.min.js"></script>
    <script src="app.js"></script>
    <style>
      .emptyMessage {
        font-weight: bold;
        color: red;
        font-size: 1.2em;
      }
      li {
        margin-bottom: 7px;
        font-size: 1.2em;
      }
      li > button {
        margin-left: 6px;
      }
      button > span {
        color: green;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <h1>Shopping List Check Off</h1>

      <div class="row">
        <!-- To Buy List -->
        <div class="col-md-6" ng-controller="ToBuyController as toBuy">
          <h2>To Buy:</h2>
          <ul>
            <li ng-repeat="item in toBuy.list">
              Buy {{ item.name }} {{ item.quantity }}
              <button ng-click="toBuy.bought($index)" class="btn btn-default">
                <span class="glyphicon glyphicon-ok"></span> Bought
              </button>
            </li>
          </ul>
          <div ng-if="!toBuy.list.length" class="emptyMessage">Everything is bought!</div>
        </div>

        <!-- Already Bought List -->
        <div class="col-md-6">
          <h2>Already Bought:</h2>
          <ul>
            <li ng-repeat="item in bought.list">Bought {{ item.quantity }} {{ item.name }}</li>
          </ul>

          <div ng-if="!bought.list.length" class="emptyMessage">Nothing bought yet.</div>
        </div>
      </div>
    </div>
  </body>
</html>

App.js

(function() {
  'use strict';

  angular
    .module('ShoppingListCheckOff', [])
    .controller('ToBuyController', ToBuyController)
    .controller('AlreadyBoughtController', AlreadyBoughtController)
    .service('ShoppingListCheckOffService', ShoppingListCheckOffService);

  ToBuyController.$inject = ['ShoppingListCheckOffService'];
  function ToBuyController(ShoppingListCheckOffService) {
    var toBuy = this;

    toBuy.list = ShoppingListCheckOffService.getList(1);

    toBuy.bought = function(itemIndex) {
      ShoppingListCheckOffService.transfer(itemIndex);
    };
  }
  AlreadyBoughtController.$inject = ['ShoppingListCheckOffService'];
  function AlreadyBoughtController(ShoppingListCheckOffService) {
    var bought = this;

    bought.list = ShoppingListCheckOffService.getList(2);
  }
  function ShoppingListCheckOffService() {
    var service = this;

    // List of shopping items
    var list1 = [
      { name: 'Cookies', quantity: 10 },
      { name: 'Bananas', quantity: 100 },
      { name: 'Toys', quantity: 6 },
      { name: 'Dildos', quantity: 300 },
      { name: 'Yaakovs', quantity: 1 }
    ];

    var list2 = [];

    service.transfer = function(itemIndex) {
      list2 = list2.concat(list1.splice(itemIndex, 1));
      console.log('List 1', list1);
      console.log('List 2', list2);
    };

    service.getList = function(num) {
      if (num == 1) {
        return list1;
      }
      if (num == 2) {
        return list2;
      }
    };
  }
})();

1 Answer 1

1

The issue is that concat does not change the original array. It creates a new array. When you do list2 = list2.concat(list1.splice(itemIndex, 1)); you are setting list2 to a new array but bought.list is still set to the old array so it doesn't change.

One solution would be to

replace

list2 = list2.concat(list1.splice(itemIndex, 1));

with

list2.push(list1.splice(itemIndex, 1)[0]);

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

3 Comments

Hey @georgeawg, thanks for taking the time to edit my answer. I'm curious what the thinking is behind your edit. Why give the replace part a yellow background (and not do the same to the with part)?
The yellow background indicates erroneous code. While white background indicates correct code.
@RockySims Ah that makes sense! Rookie mistake.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.