Darrel Holt
Darrel Holt

Reputation: 910

Angular directive ng-model working for arrays but not string

The ng-model directive seems to be lacking a reference to the actual object within the JavaScript, but only for string values. Using the list of dictionary objects and looping over the elements with ng-repeat as shown below though, it works.

I can only think that it may be due to returning the array acts like returning a reference to the object, whereas returning the string variable is simply returning the literal string, neutralizing the Angular's ability to do it's two-way data binding and leaving me with a variable that still holds a value of undefined.

Why is my service module below unable to pull the updated value from the view for the variable gitRelease?

In a service module I have this functionality:

(function () { //start iife

    'use strict';

    angular.module('gms.autoDeploy')
        .factory('AutoDeployService', ["$http", "$q", "$log", "$cookies", "APP_CONFIGS", "SweetAlert", "$timeout", "GridSettingsService", "APP_USER", AutoDeployService]);

    function AutoDeployService($http, $q, $log, $cookies, APP_CONFIGS, $timeout, SweetAlert, GridSettingsService, APP_USER) {

        var tibcoCopyJobs = [];
        var gitRelease = "";

        function addNewTibcoCopyJob() {
            tibcoCopyJobs.push({
                sourceServer: "",
                sourcePath: "",
                destinationServer: "",
                destinationPath: ""
            });
        }

        function getTibcoCopyJobs() { return tibcoCopyJobs; }
        function getGitRelease(){ return gitRelease; }

        function extractFormData() {
            console.log(gitRelease);
            for (var i = 0; i < tibcoCopyJobs.length; i++) {
                console.log(tibcoCopyJobs[i]);
            }
        }

        return {
            addNewTibcoCopyJob:             addNewTibcoCopyJob,
            getTibcoCopyJobs:               getTibcoCopyJobs,
            getGitRelease:                  getGitRelease,
            extractFormData:                extractFormData
        };
    } //end AutoDeployService
}()); //end iife

Using it with this controller:

angular.module("gms.autoDeploy").controller('AutoDeployController', ['$scope', '$compile', 'AutoDeployService',
function ($scope, $compile, AutoDeployService) {

        var model = this;

        init();

        function init() {
            model.tibcoCopyJobs = AutoDeployService.getTibcoCopyJobs();
            model.gitRelease = AutoDeployService.getGitRelease();
        }

        function btn_addNewTibcoCopy() { AutoDeployService.addNewTibcoCopyJob(); }

        function btn_extractFormData() { AutoDeployService.extractFormData(); }

        model.btn_addNewTibcoCopy = btn_addNewTibcoCopy;
        model.btn_extractFormData = btn_extractFormData;
    }
]);

To give functionality to this view:

<div ng-controller="AutoDeployController as autoDeploy">
<div class="container-fluid">

<div class="row">
    <div class="col-md-2">
        <input type="text" class="form-control" ng-model="autoDeploy.gitRelease" placeholder="MM-DD-YYYY">
    </div>
</div>

<div class="row">
    <fieldset class="col-md-2" style="margin-bottom: 10px" ng-repeat="item in autoDeploy.tibcoCopyJobs track by $index">
        <legend>Copy</legend>

        <input type="text" class="form-control" placeholder="Source Server..." ng-model="item.sourceServer">
        <br/>
        <input type="text" class="form-control" placeholder="Source Path..." ng-model="item.sourcePath">
        <br/>
        <input type="text" class="form-control" placeholder="Destination Server..." ng-model="item.destinationServer">
        <br/>
        <input type="text" class="form-control" placeholder="Destination Path..." ng-model="item.destinationPath">
    </fieldset>
</div>

<button ng-click="autoDeploy.btn_extractFormData()">extract</button>
<button ng-click="autoDeploy.btn_addNewTibcoCopy()">TIBCO copy</button>
</div>
</div>

Upvotes: 0

Views: 125

Answers (1)

Charlie Ng
Charlie Ng

Reputation: 640

I think you have explained why in your question. Array is returned by reference, whereas string is just copied by value. But I will try to make it a bit more clear.

When you do

model.gitRelease = AutoDeployService.getGitRelease();

the model object will create property getRelease like this:

{getRelease: "", ... (more properties from the ctrl)}

so whatever you update in the view it will just update the getRelease in the controller.

One possible fix is like what Jags mentioned in the comment.

Or you can make a reference to your service in the ctrl

var model = this;
model.autoDeployService = AutoDeployService;

In your view

<input type="text" class="form-control" ng-model="autoDeploy.autoDeployService.gitRelease" placeholder="MM-DD-YYYY">

that should work.

Upvotes: 1

Related Questions