What is the reason for not being able to locate the controller of the necessary directive within AngularJS?

A couple of angularjs directives were written, with one being nested inside the other.

Here are the scripts for the directives:

module.directive('foo', [
   '$log', function($log) {
     return {
      restrict: 'E',
      replace: true,
      transclude: true,
      template: '<div id="test" ng-transclude></div>',
      controller: function($scope) {
        this.scope = $scope;
        return $scope.panes = [];
      },
      link: function(scope, element, attrs) {
        return $log.log('test1', scope.panes);
      }
    };
  }
]);

module.directive('bar', [
  '$log', function($log) {
    return {
      restrict: 'E',
      replace: true,
      transclude: true,
      require: '^?foo',
      controller: function($scope) {
        return this.x = 1;
      },
      template: '<div ng-transclude></div>',
      link: function(scope, element, attrs, fooCtrl) {
        return $log.log('test2', fooCtrl);
      }
    };
  }
]);

Below is a snippet of html:

<foo ng-controller="IndexController">
      <bar></bar>
    </foo>

The generated element was inspected using Chrome developer tools:

<div id="test" ng-transclude="" ng-controller="IndexController" class="ng-scope">
      <div ng-transclude="" class="ng-scope"></div>
    </div>

Chrome console output:

test2 
Array[0]
length: 0
__proto__: Array[0]
 angular.js:5930
test1 
Array[0]
length: 0
__proto__: Array[0]  

Question: The child directive is unable to access the parent directive's controller, resulting in the fourth parameter "fooCtrl" in the link function of "bar" being an empty array. What mistake have I made?

Update and Answer:

After further investigation, I discovered a simple error that caused the unexpected outcome:

 // in directive "foo"
 controller: function($scope) {
    this.scope = $scope;
    // The following line is incorrect. It was included 
    // due to transcompiling from coffeescript to js.
    // return $scope.panes = [];
    // It should be revised as follows:
    $scope.panes = []
    // The .coffee script should appear like below
    // controller: ($scope) ->
    //     @scope = $scope
    //     $scope.panes = []
    //     return # prevent coffeescript returning the above expressions.
    //     # I should rather have added the above line
  }

After correcting this mistake, it was verified that there are no obstacles in utilizing controllers or providing data in child directives.

Answer №1

From my understanding, it is not possible to have a controller within the child directive.

Check out the demo here: http://plnkr.co/edit/kv9udk4eB5B2y8SBLGQd?p=preview

app.directive('foo', [
   '$log', function($log) {
     return {
      restrict: 'E',
      replace: true,
      transclude: true,
      template: '<div id="test" ng-transclude></div>',
      controller: function($scope) {
        $scope.panes = ['Item1','Item2','Item3'] 
        return { 
          getPanes: function() { return $scope.panes; }
        };
      },
      link: function(scope, element, attrs, ctrl) {
        $log.log('test1', ctrl, ctrl.getPanes(), scope.panes);  
      }
    };
  }
]);

The child controller has been removed in this example.

app.directive('bar', [
  '$log', function($log) {
    return {
      restrict: 'E',
      replace: true,
      transclude: true,
      require: '^?foo',
      template: '<div ng-transclude></div>',
      link: function(scope, element, attrs, ctrl) {
        scope.x = 1;
        $log.log('test2', ctrl, ctrl.getPanes(), scope.panes, scope.x);
      }
    };
  }
]);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a syntax error in Javascript when using a string and variable with the GET method?

Is there a way to send a value using the get method? In JavaScript, we need to use the + symbol to concatenate strings. But my issue goes beyond this simple problem. If I attempt the following: Let's say; var sID = 16; var rID = 17; EDIT-2: I act ...

Is it feasible to showcase collections from MongoDB and every individual element from all collections on a single EJS page?

I am currently working on developing a forum for my website using NodeJs, Express, MongoDB, and EJS for HTML rendering. However, I encountered an error message saying: "cannot set headers after they are sent to the client." I am a bit confused about this i ...

Tracking the email field in a React form with refs

Hey there! I'm a music engineer working on my own personal website using React. I'm currently facing an issue with creating a contact form that allows users to input a subject in a text field, a message in a textarea, and then click a "reach out" ...

Sorting table tbody elements created dynamically with JavaScript on an npm webpack application is not possible with jQuery UI

My JS-built table is populated with data from a JSON file fetched after a request. I want to be able to drag and drop these tbodys and update the JSON file accordingly. To handle sorting, I decided to use jquery-ui. While .sortable() works well for drag a ...

I'm trying to determine in Stencil JS if a button has been clicked in a separate component within a different class. Can anyone assist

I've created a component named button.tsx, which contains a function that performs specific tasks when the button is clicked. The function this.saveSearch triggers the saveSearch() function. button.tsx {((this.test1) || this.selectedExistingId) && ...

Having trouble replacing using String.replace() in Javascript?

I am working on a project that involves parsing a website and retrieving information from a database. The code I have looks like this: var find = body.match(/\"text\":\"(.*?)\",\"date\"); After running the code, I get the fo ...

Hold off on running the code until the image from the AJAX request is fully loaded and

Currently, I am facing a challenge with my code that aims to determine the width and height of a div only after it has been loaded with an image from an AJAX request. The dimensions of the div remain 0x0 until the image is successfully placed inside it, c ...

Create random animations with the click of a button using Vue.js

I have three different lottie player json animation files - congratulations1.json, congratulations2.json and congratulations3.json. Each animation file is configured as follows: congratulations1: <lottie-player v-if="showPlayer1" ...

React conditional statement within a map function embedded in a JSX element

Below is the function I have created to generate tabbed items: function ConstructTabs(props) { const tabs = props.tabs; const makeTabs = tabs.map((tab, index) => { <React.Fragment> <input className="input-tabs" id ...

React Hooks findByID method is throwing an error stating that it cannot read the property 'params' because it is undefined

As I dive into learning React hooks, I'm realizing that it's crucial to stay up-to-date with the latest trends in web development. Despite hours of research and tinkering around, I can't seem to wrap my head around some key concepts. The fac ...

Sending the axios fetched property from the parent component to the child component results in the error message "TypeError: Cannot read property 'x' of undefined"

I've noticed that this question has been asked before, but none of the solutions provided seem to work for my situation. Parent component import axios from "axios"; import { useEffect, useState } from "react"; import Child from &q ...

What is the most effective method for identifying the initial timestamp for each day, week, or month within a collection of timestamps?

I am dealing with a lengthy array of sorted timestamps representing stock price quotes. These timestamps have minimal resolution, meaning that each timestamp is at least 1 minute bigger than the previous one. However, there can be gaps during the day, espe ...

Enhancing Angular select functionality by incorporating HTML entities using ng-option

My query is somewhat linked to this specific response, although with a slight variation. What I am aiming to accomplish is the parsing of HTML entities from a string passed onto a select using ng-options. Consider the following dataset: $scope.myOptions ...

establishing communication between the angular controller and route controller

index.html <body> <div data-form-modal > <form> <input type='text' name='test'/> <input type='submit' value='submit' ng-click='submit()'/&g ...

refreshing the webpage with information from an API request

I am completely new to web development, so please bear with me. I am attempting to make a simple API call: const getWorldTotal = async () => { const response = await fetch('https://cors-anywhere.herokuapp.com/https://health-api.com/api/v1/cov ...

Is it a cookie-cutter function?

Can someone help me solve this problem: Implement the special function without relying on JavaScript's bind method, so that: var add = function(a, b) { return a + b; } var addTo = add.magic(2); var say = function(something) { return something; } ...

Changing states in next.js is not accomplished by using setState

Struggling to update the page number using setCurrentPage(page) - clicking the button doesn't trigger any state change. Tried various methods without success. Manually modified the number in useState(1) and confirmed that the page did switch. import ...

Dynamically Loading CSS files in a JQuery plugin using a Conditional Test

I'm trying to figure out the optimal way to dynamically load certain files based on specific conditions. Currently, I am loading three CSS files and two javascript files like this: <link href="core.min.css" rel="stylesheet" type="text/css"> & ...

Is it possible to trigger JavaScript after loading a page in jqTouch with AJAX?

Similar to the kitchensink demo, I have successfully used jqtouch to call external .html pages into the index page. One of these external pages contains a video that is being played using sublime player. Everything is pretty basic so far, but my challenge ...

I am trying to access the id of the button that was selected, but I am unsure of how to retrieve the id from it. The method of using

I am trying to retrieve the id of a selected button for deletion purposes. However, I am unable to get the id from it using 'this.id'. Is there another method I should be using? Below is the code where I create the button: var deleteEmployer= d ...