Sign up ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free.

On my page I have a dynamic list of musicians (players) whereas a player can be removed and added to the list. Each player shall have multiple instruments which is also a dynamic list, whereas an instrument can be added or removed from a player's instrument list. So we are talking about two nested dynamic lists.

Here is the code and the problem description under it.

jamorg.html:

<!DOCTYPE html>
<html ng-app='jamorgApp'>
<head>
    <link rel="stylesheet" type="text/css" href="C:\Users\jazzblue\Documents\Bootstrap\bootstrap-3.3.2-dist\css\bootstrap.min.css" />
    <title>Jam Organizer</title>
</head>

<body>
<div ng-controller='JamOrgController as jamOrg'>
<h1>Jam</h1>
<div ng-repeat='player in players'>

    <div>
        <h3 style="display: inline-block;">player {{$index}}</h3>
        <button ng-click="removePlayer($index)">Remove</button>
    </div>

    <br/>


    <div ng-controller='JamOrgPlayerController as jamOrgPlayer'>
        <div ng-repeat='instrument in player'>
            <span>Instrument: {{instrument.instrument}},</span>
            <span>Level: {{instrument.level}}</span>
            <button ng-click="remove($index)">Remove</button>
        </div>

        <button ng-click="addInstrument()">Add Instrument</button>
        Instrument: <input ng-model='newInstrument.instrument'>
        Level: <input ng-model='newPlayer.level'>
    </div>

</div>
</div>
    <script type="text/javascript" src="C:\Users\jazzblue\Documents\AngularJS\angular.min.js"></script>
    <script type="text/javascript" src="jamorgApp.js"></script>
</body>
</html>

jamorgApp.js

var app = angular.module('jamorgApp', []);

app.controller('JamOrgController', ['$scope', function($scope){
    $scope.players = players;

    $scope.removePlayer = function(index) {
        $scope.players.splice(index, 1);
    } 

    }]);

app.controller('JamOrgPlayerController', ['$scope', function($scope){

    $scope.newInstrument = newInstrument;

    $scope.remove = function(index) {
        $scope.player.splice(index, 1);
    } 

    $scope.addInstrument = function() {
        $scope.player.push(newInstrument);
    } 

}]);

var players = [
    [{instrument: 'Guitar', level: 3}, {instrument: 'Keyboard', level: 3}],
    [{instrument: 'Bass', level: 4}],
    [{instrument: 'Drums', level: 3}]
];

var newInstrument = [
    {instrument: 'x', level: 'y'}
]

Here is my problem: the same newInstrument is being added to all the different players lists which is wrong: each player's instrument list should have its own newInstrument.

How should I change it to get the right design? Thanks!

share|improve this question

2 Answers 2

up vote 2 down vote accepted

Where you do:

$scope.addInstrument = function() {
        $scope.player.push(newInstrument);
    } 

Try doing:

$scope.addInstrument = function() {
        $scope.player.push(angular.copy(newInstrument));
    } 

Update:

In your HTML:

<button ng-click="addInstrument(player)">Add Instrument</button>

In your JS:

$scope.addInstrument = function(player) {
            player.push(angular.copy(newInstrument));
        }

UPDATE

I created a fiddle where you can check some possible modifications to your code. It uses just one controller and fixes the duplicated object issues.

share|improve this answer
    
Thanks, but it does not appear to work. As with the original code, anything that is entered (in the browser) as new instrument for player 1 is automatically replicated to all other players, meaning that I did copy the object but that one copy went to all the players. –  jazzblue Jul 11 at 3:38
2  
Hmmm now i am seeing your code again. What is $scope.player? Because i see $scope.players but not $scope.player. Check my updated answer to see if it works. –  Mindastic Jul 11 at 3:43
    
I think you did find a bug with $scope.player, I give you a point for your comment, however, the solution you suggest still does not work for me. I think, the problem is that the same copy of newInstrument is pushed to different players. I need, however, a separate copy for each player or something like that. Have you tried your suggestion? Thanks. –  jazzblue Jul 11 at 5:05
    
@jazzblue can you create a fiddle with your code and share? It might help us understanding it and helping you. –  Mindastic Jul 11 at 14:29
1  
I cannot run that fiddle. It throws an error. Anyway, i tried it on my computer and it works but once you add a new instrument and then continue typing in the input, the just added instrument is modified too. I worked on some code that removes all your controllers (i think it is unnecessary to have so many controllers for your little piece of code) and works OK to. Check this fiddle: jsfiddle.net/6Lxw70cy/1 . –  Mindastic Jul 11 at 17:41
<button ng-click="addInstrument($index)">Add Instrument</button>
    Instrument: <input ng-model='newInstrument.instrument'>
    Level: <input ng-model='newPlayer.level'>

and your addInstrument function should be like this

$scope.addInstrument = function(index) {
    $scope.players[index].push($scope.newInstrument);
}
share|improve this answer
    
Thanks, but this still does not work properly: on the page when you type value of "new instrument" in the text box for Player 1 it is automatically replicated to "new instrument" of all other players while you are typing. I need different instances of that model for different players. Is there any way to achieve it? Thanks. –  jazzblue Jul 11 at 14:24
    
you need just something like in this in your ng-model newInstrument[$index].instrument and newPlayer[$index].level. it will creat separate model for each player. –  chiragchavda.ks Jul 11 at 14:29
    
Actually I found a way: I need a separate controller for NewInstrument, then it will create "separate instances". Your suggestion to use ng-model was very valuable. Thanks. –  jazzblue Jul 11 at 14:41
    
i am glad that you sort it out.Happy to Help :) –  chiragchavda.ks Jul 11 at 14:54

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.