0

I have a $scope that needs to show the iso code on select from a list of countries.

So the countries list is being fetched a $http call factory and it populates into a scope, so far so good here

///////// get countries ////////////////
tableFactory.getCountries().then(function(data){
  $scope.presentCountries = data;
});

presentCountries will be sent into typeahead where the user will type for a country and select it, like so:

<div class="countrySearchField">
    <div class="row">
        <h3 class="searchTitle">Pick a country</h3>
    </div>
    <input type="text" class="form-control search-input" ng-model="countryPicked" uib-typeahead="presentCountry.name for presentCountry in presentCountries | filter:{name: $viewValue}:startsWith" typeahead-min-length="1" typeahead-on-select="onSelectCountry($item, $model, $label)" typeahead-editable="false"/>
</div>

Once it's selected, it will call the scope function onSelectCountry.

$scope.onSelectCountry = function($item, $model, $label){
    $scope.brandCountryCode = $item.iso_code_2;
    // $scope.brandCountryCode = $item;
    console.log($scope.brandCountryCode);

}

I can see the data,$scope.brandCountryCode, in the console from console.log, but not in the modal view(overlay view).

<div class="row subtitleModalRow">
    <h5 class="unlock-description">Please check the following parameters before merging</h5>
    <!-- <p class="unlock-description" ng-bind-html="overlayMessage"></p> -->
    <ul>
        <li>Brand Country: {{brandCountryCode}}</li>

    </ul>
</div>

I don't understand why it's not showing up, but I can see the console.log output. I'm suspecting is because the scope is under a function, but I thought if you set a value into a $scope, it should be available anywhere, please correct me if I'm wrong.

Also, it could be that the overlay view is a separate html file from the typeahead html. However, this overlay view has the controller, tablePageCtrl. The controller should be present in both html files.

this.openModal = function(type) {

    this.type = type;

    if(type == 'mergeRequest'){
        var templateUrl = 'app/views/dataMerge/overlayMsg.html';
        var backdropClass = 'auth-backdrop';
        var controller = 'tablePageCtrl';
    }

    this.modalInstance = $uibModal.open({
        animation: true,
        templateUrl: templateUrl,
        controller: controller,
        windowTopClass: 'auth-template',
        backdrop: 'static',
        backdropClass: backdropClass,
     });
};

I did a test, outside the function called $scope.test = 'test' in the controller, and I see the value in the overlay view. I have other scopes based onSelect function that are running into this situation, and they all are under a $scope function.

I added an initializer, $scope.brandCountryCode = '', but it didn't do anything. If I can solve this one, then the other ones should be fine.

Not sure what's going here, does anybody have any suggestions. Still new to Angular and your help will be appreciated. Thanks!

EDIT

full service code for the overlay modal:

(function() {
  'use strict';

  angular
  .module('com.xad.se-tools')
  .service('tableModalService', function($scope, $uibModal){

    this.modalInstance = null;
    this.type = null;

    this.openModal = function(type) {
      this.type = type;
      if(type == 'mergeRequest'){
        var templateUrl = 'app/views/dataMerge/overlayMsg.html';
        var backdropClass = 'auth-backdrop';
        var controller = 'tablePageCtrl';
      }

      this.modalInstance = $uibModal.open({
        animation: true,
        templateUrl: templateUrl,
        // controller: 'AuthCtrl',
        controller: controller,
        windowTopClass: 'auth-template',
        backdrop: 'static',
        backdropClass: backdropClass,
        scope: $scope
      });
    };

    this.closeModal = function() {
      this.modalInstance.dismiss('cancel');
    }

  });

})();
medev21
  • 2,469
  • 8
  • 31
  • 43
  • 2
    You are probably a victim of [JavaScript Prototype Inheritance](http://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs). Essentially, the modal has a different scope than the parent page, and the values on the page are hidden. You can either use the answer provided by @Bartekfyzowicz, (force the modal to use the same scope) or, follow the **golden rule** in angular: **"Always use a dot in angular bindings."**. – Claies Feb 23 '17 at 18:07

1 Answers1

3

I think that you should set scope config option in your modal instance to set scope used in modal:

  this.modalInstance = $uibModal.open({
        animation: true,
        templateUrl: templateUrl,
        controller: controller,
        windowTopClass: 'auth-template',
        backdrop: 'static',
        backdropClass: backdropClass,
        scope: $scope
      });

Please check angular bootstrap modal documenation here for more details.

Bartek Fryzowicz
  • 6,464
  • 18
  • 27
  • I'm having some issues adding the scope into the service, I get an injection error. I added the code in the question. – medev21 Feb 23 '17 at 18:19
  • 1
    @medev21 services don't have access to the `$scope` object. Creating a modal from a service isn't really right anyway; `$uibModal` is a service, and calling a service to make a call to another service gets messy. – Claies Feb 23 '17 at 18:31
  • In addition to @Claies comment: you can create an instance of modal directly in controller which scope you need in the modal. – Bartek Fryzowicz Feb 23 '17 at 18:37
  • I did what you guys suggested in this actually worked. Thanks! – medev21 Feb 23 '17 at 21:13