Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass a variable between controller and use ng-repeat on same page

Some of my wording may be off especially regarding angular/js terminology (controller, service, factory, etc), but hopefully it is still understandable. Also, this question has multiple parts, which made it difficult to ask in one line.

I have 3 files: newRegistration.html, Registration.js, and addressVerification.js.

In newRegistration.html, there is a form where the user inputs his/her email, phone, mailing address, and other things and then clicks "next". Upon clicking next, Registration.js (a controller?) is triggered (?).

newRegistration.html

In the following snippet is the ng-repeat that I'd like to update with new data from addressVerification.js.

<div id="dialog-form" title="CHOOSE THE CORRECT ADDRESS">
    <ul>
        <li ng-repeat="for item in [not sure what to put here because of two js files]">

        </li>
    </ul>    
</div>

Registration.js

The controller for the template that contains the ng-repeat mentioned above.

The top line looks like this:

angular.module('appname')
    .controller('RegistrationCtrl', function ($scope, $http, cacheStore, countryStates, birthYear, $anchorScroll, errorMessages, addressVerification, UtilsFactory)

And this is a line that may be relevant:

addressVerification.verify(user).then(function (userObj) 

addressVerification.js

Uses the Smartystreets API to correct/suggest the mailing address.

I can't figure out how to pass variables from this module to Registration.js (where the scope variable [?] is) in order to populate the ng-repeat in newRegistration.html.

angular.module('appname').factory('addressVerification', function($q, userIdentity, $http,  smartyToken) {
    "use strict";

    return {
    verify: function(obj) {
        var deferred = $q.defer(),
        street2QS = "";

    if (obj.address2 || obj.address2 !== "") {
        street2QS = "&street2=" + encodeURIComponent(obj.address2);
    }

$http.jsonp("https://api.smartystreets.com/street-address?street=" + encodeURIComponent(obj.address1)
    + street2QS
    + "&city=" + encodeURIComponent(obj.city)
+ "&state=" + encodeURIComponent(obj.state)
+ "&zipcode=" + encodeURIComponent(obj.zip)
+ "&source=website&auth-token="+ smartyToken.get() + "&candidates=5&callback=JSON_CALLBACK")
.success(function (response) {
    var metaData,
    components;

        if (response && response.length === 1) {
        metaData = response[0].metadata || {};
        components = response[0].components || {};

            angular.extend(obj, {
        "address1": [
            components.primary_number,
        components.street_name,
        components.street_suffix
                    ].join(" "),
        "address2": [
        components.secondary_designator,
        components.secondary_number
        ].join(" "),
        "city": components.city_name,
        "county_name": metaData.county_name,
        "county_fips": metaData.county_fips,
        "state": components.state_abbreviation,
        "latitude": metaData.latitude,
        "longitude": metaData.longitude,
        "plus4_code": components.plus4_code,
        "zip": components.zipcode
        });
        deferred.resolve(obj);
        } else {
            deferred.reject(false);
        }
        }).error( function() {
            deferred.reject(false);
        });

        return deferred.promise;
    }
    };
});

I'm pretty clueless right now. I think I've given all of the necessary details. I wish I knew where to start. I read all about deferred objects, ng-repeat, and controllers, but it's confusing me.

Any help appreciated.

like image 435
Emil Avatar asked Mar 28 '26 18:03

Emil


2 Answers

You're injecting addressVerification into RegistrationCtrl. The value of addressVerification that is injected into the RegistrationCtrl is the value returned by executing the function you're defining here:

angular.module('appname')
.factory('addressVerification', function($q, userIdentity, $http, smartyToken)

Therefore you can access the stuff that's happening inside of the addressVerification.js file in the RegistrationCtrl.js file by adding methods to whatever it is you're returning in that function.

Once you have your data in RegistrationCtrl, you can access it from the view by appending data to the scope inside of RegistrationCtrl. Example:

This would go in RegistrationCtrl.js:

$scope.someItems = [1, 2, 3, 4];

This would go in the view:

<li ng-repeat="item in someItems">{{item}}</li>
like image 115
patorjk Avatar answered Mar 31 '26 10:03

patorjk


The way that I have implemented this is by exposing methods of a factory that allow the controllers (and the controller's view(s)) that depend on it to store values within the same factory.

For example, in the following code, the setCurrent method of the customers factory stores a value, current in the factory. Because factories are singletons, will persist in the application. Even after the user's click on the <a> (in the following example) and they are taken to href="/", the value that was stored in customers.current will be accessible to the "/" route's controller if the same factory is a dependency for both controllers.

Template

<ul>
    <li>{{customers.current.name}}</li>
    <li 
        ng-repeat="customer in customers.all"
        >
        <a 
            class="action name"
            ng-click="customers.setCurrent(customer)"
            href="/"
            >
            {{customer.name}}
        </a>
    </li>
</ul>

Controller

angular
.module('CtrlCustomerList', [
    'CollectionCustomers',
])
.controller('CtrlCustomerList', function($scope, CollectionCustomers) {
    $scope.customers = CollectionCustomers;
});

Factory

angular
.module('CollectionCustomers', [
])
.factory("CollectionCustomers", function(Restangular, ModelCustomer, $location) {
    return {
        all     : [],
        current : null,
        setCurrent : function() {
            // Affect this.current
        }
    }
});
like image 26
Walter Roman Avatar answered Mar 31 '26 09:03

Walter Roman