0

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?

7
  • I think it's not a scope issue but the TypeError make the linking crash. You use this.getFormattedIngredients before its definition. You must define this.getFormattedIngredients before $scope.allIngredients. Commented Mar 9, 2017 at 9:07
  • still get the same issue Commented Mar 9, 2017 at 9:10
  • Are you sure your template is correct? Do you use {{$ctrl.value}} syntax? Commented Mar 9, 2017 at 9:17
  • yes, I use in the template,as an example: <h3 class="modal-title">{{panel.name}}</h3> Commented Mar 9, 2017 at 9:19
  • using {{$ctrl.panel.name}} doesn't solve the issue Commented Mar 9, 2017 at 9:21

2 Answers 2

1

Instead of scope: $scope pass values using

resolve: { scope: $scope }
Sign up to request clarification or add additional context in comments.

2 Comments

thanks, it now works. One small issue has persisted: the $uibModalInstance.close(); doesn't work, as the modal doesn't close when the OK button is closed. What change should I make to fix this?
@Anto see if $uibModalInstance is getting properly injected into the code. If not you can try $uibModalInstance.dismiss() if that serves your purpose
0

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() {}

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.