Looping through Angular's $compile function

The data for the angular app is received in an array and then used with $compile to create an angular directive. For example...

for(i = 0; i < trueTest.length; i++) {
    var test = trueTest[i];
    $scope.directiveData = {
       blockId: test.blockId,
       dataType: test.dataType,
       type: test.type,
       directiveType: test.directiveType
    };

    $compile("<my-directive block-id='{[{ directiveData.blockId }]}' block-data-type='{[{ directiveData.dataType }]}' block-type='{[{ directiveData.type }]}' block-directive-type='{[{ directiveData.directiveType }]}'></my-directive>")($scope.$new());
    elem.find('.SomeElement').append(el);
}

The custom directive my-directive has an isolated scope with values such as blockId, blockDataType, etc...

The key value here is blockId within my-directive. It determines the type of data that will be displayed in that specific directive. The issue arises when it appears that $compile creates elements after the loop has finished, resulting in each directive created by $compile having the last value from the loop.

It's speculated that $compile generates elements (directives) asynchronously, causing the directives to be created only after the loop ends, with the current values of $scope.directiveData. Alternatively, the directives may be created as plain DOM elements first, with scopes being assigned afterwards, leading all directives to have the last value of the directiveData object.

Can someone provide insight into what exactly is happening here?

EDIT

For those interested, here is a jsFiddle link showcasing the problem. While it cannot run due to code size limitations, I've added comments to explain the issue as best as possible.

Problem

SECOND EDIT.

To investigate further, console.log() was implemented. One was placed right after

elem.find('.SomeElement').append(el);
, and another console.log('just print this') inside the directive's controller. It appears that the DOM elements are created before the directive's controller is called. This suggests that all DOM elements are generated before their respective scopes are assigned.

Am I misunderstanding something?

Answer №1

The problem lies in repeatedly assigning your directiveData within the same scope, causing the previous object to be overwritten.

Perhaps consider creating a new scope at the start of the loop and then assigning the object to that specific scope?

Additionally, I have switched the order of the DOM append call and the $compile call. In my experience, this approach tends to work better (although there may be different opinions).

for(i = 0; i < trueTest.length; i++) {
    var scope = $scope.$new();
    var test = trueTest[i];
    scope.directiveData = {
       blockId: test.blockId,
       dataType: test.dataType,
       type: test.type,
       directiveType: test.directiveType
    };

    var el = $("<my-directive block-id='{[{ directiveData.blockId }]}' block-data-type='{[{ directiveData.dataType }]}' block-type='{[{ directiveData.type }]}' block-directive-type='{[{ directiveData.directiveType }]}'></my-directive>");
    elem.find('.SomeElement').append(el);
    $compile(el)(scope);
}

While I haven't tested it out yet, this revision should bring you closer to resolving the issue.

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

What is the best way to print a canvas element once it has been modified?

My goal is to include a "Print Content" button on a webpage that will print a canvas element displaying workout metrics. However, the canvas content, which consists of a visual graph of workout data, changes based on the selected workout (bench, squat, etc ...

Transforming a set of properties into an organized array

Looking to transform an object literal that contains inner objects with a "rank" key holding floating point values into an array of these inner objects, sorted by the "rank" value. Input Object: { 452:{ bla:123, dff:233, rank:2 }, 234:{ ...

A multimedia player featuring various video source files and multiple text track options

My issue involves a video element where the user can choose from a list of options to play. Each video has an associated text track, but I am having trouble setting the new text track when a different video is selected. In my html, I have: <video id ...

Retrieve the route from a specific node in the jstree structure

Looking to retrieve the paths of selected nodes in jstree? You'll need the complete path of the nodes. I have a php file that generates the JSON, structured like this: header("Content-Type: application/json; charset=utf8"); echo json_encode(dir_to_ ...

React JS Bootstrap Dropdown Troubleshooting

I'm facing a challenge in my React.js project while trying to implement a filter. The issue is that the list appears when I click on the button, but it doesn't disappear on the second click or if I click outside the list. Initially, I imported t ...

Exploring the World of Three.js Loaders

I downloaded the file package three.js-dev from threejs.org and I am trying to use it in my project like this: <script type="text/javascript" src="./build/three.js"></script> <script type="text/javascript" src="./src/loaders/JSONLoader.js" ...

Solution: Resolve clientY scrolling issue within an HTML document

I am facing an issue with the positioning of my context menu. When I right-click and scroll down, the menu does not maintain its regular position. Instead of appearing to the right of the mouse cursor when stationary, it moves below the cursor based on how ...

Using percentage values to fill a customized SVG image

I'm looking to incorporate a percentage value into a custom SVG image in Angular 6 using TypeScript or CSS. Are there any tools designed for this specific task? The custom image could be anything, such as a dollar sign, gear icon, or thumbs up symbo ...

Toggle visibility of button based on current selection

I am currently working on a script that allows users to select and press "Next" to reveal another set of steps. In order to proceed to the next step, I want to have the submit button disabled by default and only enabled if the user has made at least 2 sele ...

What is the proper way to retrieve the rootScope in Angular?

When looking at this code snippet, the controller is given an injected scope and rootScope. However, an error occurs on the last line with: ReferenceError: $rootscope is not defined angular.module("myEntity").controller('productsCtrl', [ &a ...

Delay in changing the z-index of FloatingActionButton on hover

In my current issue, I am facing a problem where a div that is meant to always stay below a FloatingActionButton (FAB) ends up temporarily appearing above it when z-index values are changed. The scenario is such that upon clicking the FAB, an invisible ove ...

React date format error: RangeError - Time value is invalid

I'm utilizing a date in my React app using the following code: const messageDate = new Date(Date.parse(createdDate)) const options = { month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric' } as const ...

Pick a selection from a different input

Consider the following two rows: <tr> <td class="contenu"><input type="text" name="numart" id="numart"/></td> <td class="contenu"><input type="text" name="descart" id="descart"/></td> <td class="contenu"& ...

Meteor: Calculate the total count of items within a related collection

I am currently working on a lists/tasks application and have encountered an issue with counting the items for each list. I am using a session to store which list I am clicking on, but the count system is only related to that specific list. I followed the M ...

Tips for reducing the amount of repetitive code in your reducers when working with redux and a plain old JavaScript object (

When it comes to writing reducers for Redux, I often encounter challenges. My struggle usually lies in wrapping a lot of my state manipulation in functions like .map and .slice. As the structure of my state object becomes more complex, the reducers become ...

Best practices for running Javascript based on PHP output

I'm trying to figure out how to add a PHP Exception to my JavaScript function that sends form data to a database. I want it to work like this: "if 'whatever' condition is met, execute the JavaScript function; otherwise, throw an Exception me ...

How can I verify if a user is logged in using express.Router middleware?

Is there a way to incorporate the isLoggedIn function as a condition in a get request using router.route? const controller = require('./controller'); const Router = require('express').Router; const router = new Router(); function isLo ...

Wait for the canvas to fully load before locating the base64 data in HTML5

Wait until the full canvas is loaded before finding the base64 of that canvas, rather than relying on a fixed time interval. function make_base(bg_img, width, height) { return new Promise(function(resolve, reject) { base_image = new Image(); base_imag ...

Issue encountered with Framer Motion: Scope is available but no element has been detected

I'm in the process of developing an exciting multiplayer game. The concept is simple: you create a game, share the link or session ID with your opponent, and they join the game. The technology stack I'm using includes React, Next.js, Firebase&ap ...

The hyperlink element is failing to load in a particular frame

I've been attempting to load the URL of an anchor tag in a specific frame. I've tried various methods through online searches, but have not found a satisfactory solution. Can someone please assist me with how to load the href URL in a particular ...