Anto
Anto

Reputation: 4305

$scope in AngularJS modal doesn't pass data into the template

I am new to AngularJS. I have created the following controller that display a list of results and that opens a modal when a specific button is clicked:

angular.
module('panelList')
  .component('panelList', {
  templateUrl: '/panel-list/panel-list.template.html',
  controller: ['Panel', 'PanelSelection', '$scope', '$location', '$uibModal',
    function PanelListController(Panel, PanelSelection, $scope, $location, $uibModal) {

      $scope.maxAbv = 2;
      $scope.minAbv = 12;
      $scope.maxIbu = 0;
      $scope.minIbu = 100;

      this.allPanelsRetrieved = (index, before, filterParams) => {
        let allPanels = before;
        const params = Object.assign({},
          { page: index, per_page: 80 },
          filterParams);
        Panel.query(params).$promise.then(data => {
          if (data.length > 0) {
            allPanels.push(...data);
            return this.allPanelsRetrieved(index+1, allPanels, filterParams);
          } else {
            return allPanels;
          }
        });
        return allPanels;
      };

      $scope.getPanels = () => {
       const filterParams = {};
       filterParams.abv_lt = $scope.minAbv;
       filterParams.abv_gt = $scope.maxAbv;
       filterParams.ibu_lt = $scope.minIbu;
       filterParams.ibu_gt = $scope.maxIbu;
       $scope.currentPagePanels = this.allPanelsRetrieved(1,[], filterParams);
      };

      $scope.showDetails = (panelSelected) => {
        PanelSelection.setPanelSelected(panelSelected);
        $uibModal.open({
          component: "panelDetail",
          scope: $scope,
          bindToController: true,
        })
      };
  }]
});

The controller for the modal is specified here:

angular.
module('panelDetail').
component('panelDetail', {
  templateUrl: '/panel-detail/panel-detail.template.html',
  controller: ['PanelSelection', '$scope','$uibModal',
    function PanelDetailController(PanelSelection, $scope, $uibModal, $uibModalInstance) {

      $scope.ok = () => {
        $uibModalInstance.close();
      };

      let panelSelected = PanelSelection.getPanelSelected();
      $scope.panel = panelSelected;
      console.log(panelSelected);
      $scope.foodPairings = panelSelected.food_pairing.join(", ");
      $scope.allIngredients = this.getFormattedIngredients(panelSelected.ingredients);
      $scope.method = this.getFormattedMethod(panelSelected.method);

      this.getFormattedIngredients = (ingredients) => {
        const listOfIngredients = [];
        Object.keys(ingredients).forEach(key => {
          if(Array.isArray(ingredients[key])){
            for(let ingredient of ingredients[key]){
              listOfIngredients.push(
                `- ${ingredient.name} ${key} (${ingredient.amount.value} ${ingredient.amount.unit})`
                  .concat(ingredient.add != undefined ? ', added in the '+ingredient.add:'',
                    ingredient.attribute != undefined ? ', attribute: '+ingredient.attribute:'','.')
              );
            }
          }else{
            listOfIngredients.push(`- ${ingredients[key]} ${key}.`);
          }
        });
        return listOfIngredients;
      };

      $scope.getFormattedMethod = (method) => {
        const listOfMethodProcedures = [];
        Object.keys(method).forEach(key => {
          if(Array.isArray(method[key])){
            for(let methodProcedure of method[key]){
              listOfMethodProcedures.push(
                `- ${key} at ${methodProcedure.temp.value} ${methodProcedure.temp.unit} `
                  .concat(methodProcedure.duration != undefined ? 'for '+methodProcedure.duration +' min.' : '.')
              );
            }
          }else{
            listOfMethodProcedures.push(`- ${key}.`);
          }
        });
        return listOfMethodProcedures;
      };
  }
  ]
});

The modal is open correctly but the values inside are not taken from the scope, as they should, but they are displayed as {{value}}. In few words, the $scope passed doesn't act as scope. Moreover I get the following error:

TypeError: this.getFormattedIngredients is not a function at new PanelDetailController

Where the error may be? How to pass successfully a scope from one controller to another for modal?

Upvotes: 0

Views: 87

Answers (2)

Founded1898
Founded1898

Reputation: 977

You are calling the getFormattedIngredients function before it gets declared. So this is not a $scope issue. You need to declare the function before it gets called. One way to solve such an issue is going with the angular Styleguide provided by John Papa. Angular Styleguide

Assign your function at the top of your Component/Controller/Service and use function expressions instead of function declarations.

function PanelDetailController(PanelSelection, $scope, $uibModal,$uibModalInstance) {

  this.getFormattedIngredients = getFormattedIngredients;

  // You can call your function from here without getting an error 
  // Other Code..
  function getFormattedIngredients() {}

Upvotes: 0

Shahzad
Shahzad

Reputation: 1703

Instead of scope: $scope pass values using

resolve: { scope: $scope }

Upvotes: 1

Related Questions