0

I have an API which takes objects e.g.

{ 
   'title': 'Some', 
   'desc': 'thing', 
   'environments': '[
           {'id': 1}, 
           {'id': 2}
    ]
}

To add new entries i have a form for setting the title and the description for the object i'm going to pass to my API:

<form class="form horizontal"role="form" ng-submit="vm.submitForm()">

        <label for="Title">Title</label>
        <input  class="form-control"
                id="Title" 
                type="text" 
                ng-model="vm.myObj.title" 
                placeholder="Title"/>

        <label for="Desc">Description</label>
        <input  class="form-control"
                id="Desc" 
                type="text" 
                ng-model="vm.myObj.desc" 
                placeholder="Description"/>

        <div class="checkbox" ng-repeat="env in vm.availableEnvs">
            <label>
                <input type="checkbox" /> 
                {{env.label}}
            </label>
        </div>

        <hr />

        <button>Submit</button>
</form>

In the form you probably saw that i had a ng-repeatthat repeats over an array of environment objects:

this.environments = [
        { id: 1, label: "US" },
        { id: 2, label: "EU" },
        { id: 3, label: "ASIA" },
        { id: 4, label: "AFRICA" }
    ];

Since the API need to get an array of: {id: x } objects, i was wondering if anyone has a good way for adding (and removing) object details to myObj.environmentsarray when you check or un-check a checkbox?

My .js code: Link to JSFiddle Here

(function(){
angular
    .module('myApp', [])
    .controller('MyCtrl', MyCtrl)
    .service('EnvService', EnvService);


MyCtrl.$inject = ['EnvService'];
function MyCtrl(EnvService) {
    var vm = this;
    vm.availableEnvs = EnvService.getAvailableEnvironments();

    vm.myObj = { 
        title: '', 
        desc: '',
        environments: [] 
    };

    vm.submitForm = submitForm;

    function submitForm() {
        //Call a service that handles $http and makes a POST with myObj                        
    }

}

function EnvService() {
    this.environments = [
        { id: 1, label: "US" },
        { id: 2, label: "EU" },
        { id: 3, label: "ASIA" },
        { id: 4, label: "AFRICA" }
    ];

    this.getAvailableEnvironments = function() {
        return this.environments;   
    }
}
})();

2 Answers 2

2

What I do in such cases is outlined as follows:

  1. Make an intermediate array, holding the set memberships, i.e. intermediateArray[i] is true if mainArray[i] is included in the post data. Obviously bind intermediateArray[i] to the i-th checkbox.
  2. Do a $watchCollection on the intermediateArray and set the target collection accordingly.

The forked fiddle: http://jsfiddle.net/Lz23r2hd/

(In the fiddle I also changed the service to return a promise - I believe it is a best practice, but non-essential for this answer.)

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

1 Comment

Exactly the result i wanted and i really appreciate you took the time to improve my code to return a promise instead. Now i don't need to ask a question about that (which was almost due...)! :) Ty sir.
0

I would add an ng-click and use the $event arg to processes what state that checkbox is beign set to(true or false)

Then you pass that and the corresponding id to an update function which will update the vm.myObj.environments array accordingly without the need of a temp array. A deselect would remove and a select would add.

<input type="checkbox" ng-click="vm.toggleEnv($event, env.id)" />{{env.label}}</label>

and here would be the updated functions:

    vm.toggleEnv = function ($event, id) {
        //Get the checkbox that was clicked
        var chbx = $event.target;

        //Depending on the status, different actions should be taken
        vm.updateEnv(chbx.checked, id);
    };

    vm.updateEnv = function (isChecked, envId) {
        //If the Deselect
        if (!isChecked) {
            for (var i = 0; i < vm.myObj.environments.length; i++) {
                //Check to see if the id's match
                if (vm.myObj.environments[i].id == envId) {
                    //Remove the Item
                    vm.myObj.environments.splice(i, 1);
                    break; //Exit the loop
                }
            }
        } else {
            //Add the item
            vm.myObj.environments.push({
                id: envId
            });
        }
    };

Here is a forked fiddle: http://jsfiddle.net/xe9aL1ch/

Comments

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.