The binding on an AngularJS page is only retained by the final directive applied

Having a few directives that need to be reused as elements, I've decided to implement scope isolation. Each directive is associated with its own controller, which retrieves data from MongoDB based on the URL.

The issue I'm facing is that only the last directive on the page is displaying the data it's supposed to. It doesn't matter what order I place the directives in, only the last one seems to work, although each one does function individually. For example, I can see the customer dump in the log, but unless it's the last directive on the page, nothing appears in {{ here }}.

I suspect this may be a scope problem, but these directives are meant to be isolated for reusability. So, why are they seemingly conflicting with each other?

Here is the code snippet:

JS

.controller('getCustomerList',function(customerIOService){
    _this = this;
    _this.customers = {};
    customerIOService.list()
                    .success(function(data, status, headers, config){
                        _this.customers = data;
                    })
                    .error(function(data, status, headers, config){
                        console.log('error Data :: ');
                        //console.log(data);
                        if(status == 403){
                            _this.error = 'You need to be logged in to view this page.';
                        }else{
                            _this.error = 'An error occured during the customer list request.';
                        }
                    });
})
.controller('getCustomerAppointments',function(customerIOService){
    _this = this;
    _this.appointments = {};
    customerIOService.getAppointments()
                    .success(function(data, status, headers, config){
                        _this.appointments = data;
                    })
                    .error(function(data, status, headers, config){
                        console.log('error Data :: ');
                        if(status == 403){
                            _this.error = 'You need to be logged in to view this page.';
                        }else{
                            _this.error = 'An error occured during the appointments list request.';
                        }
                    });
})
.controller('getCustomerSingle', function(customerIOService) {
    _this = this;
    _this.customer = {};
    _this.updateSuccess = false;

    customerIOService.one()
                    .success(function(data, status, headers, config){
                        _this.customer = data;
                    })
                    .error(function(data, status, headers, config){
                        console.log('error Data :: ');
                        if(status == 403){
                            _this.error = 'You need to be logged in to view this page.';
                        }else{
                            _this.error = 'An error occured during the customer fetch request.';
                        }
                    });

    _this.update = function(){
        customerIOService.update(_this.customer)
                    .success(function(data, status, headers, config){
                        _this.customer = data;
                        _this.updateSuccess = true;
                    })
                    .error(function(data, status, headers, config){
                        console.log('error Data :: ');
                        if(status == 403){
                            _this.error = 'You need to be logged in to view this page.';
                        }else{
                            _this.error = 'An error occured during the customer update.';
                        }
                    });
    }
})
.directive('customerList',function() {
    return {
      scope: {},
      restrict:'E',
      templateUrl: 'views/templates/customersList.html',
      replace: true,
      controller: 'getCustomerList',
      controllerAs: 'ctrl'
    };
})
.directive('customerSingle',function() {
    return {
      scope: {},
      restrict:'E',
      templateUrl: 'views/templates/customersSingle.html',
      replace: true,
      controller: 'getCustomerSingle',
      controllerAs: 'singleCustCtrl'
    };
})
.directive('customerAppointments',function() {
    return {
      scope: {},
      restrict:'E',
      templateUrl: 'views/templates/customersAppointmentsList.html',
      replace: true,
      controller: 'getCustomerAppointments',
      controllerAs: 'custApptCtrl'
    };
})

Parent HTML

<section>
    <div class="sectionHeader oswald font-light panel panel-default panel-body panel-success text-center">Customer Update</div>

    <div class="panel panel-default panel-body panel-success">
        <customer-single></customer-single>
    </div>

    <div class="panel panel-default panel-body panel-success">
        <customer-appointments><customer-appointments/>
    </div>

    <div class="panel panel-default panel-body panel-success">
        <customer-list><customer-list/>
    </div>
</section>

Directive HTML

<span>
    <a href="/appointments/create/{{custApptCtrl.customer._id}}">
            <span class="fa-stack fa-lg pull-left">
                <i class="fa fa-plus fa-stack-1x "></i>
            </span>
            Add Appointment
        </a>

<table class="table table-striped">
    <thead>
      <tr>
        <th>Caregiver</th>
        <th>Start</th>
        <th>End</th>
        <th>Actions</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="appt in custApptCtrl.appointments">
        <td>{{ appt.employee.lastName }}, {{ appt.employee.firstName }}</td>
        <td>{{ appt.startDate }}</td>
        <td>{{ appt.endDate }}</td>
        <td><a href="/appointments/{{appt._id}}"><span class="glyphicon glyphicon-pencil"></span></a></td>
      </tr>
   </tbody>
</table>
</span>

Answer №1

It appears that your controllerAs syntax may not be quite right. I suggest trying the following approach:

Update your controller:

    app.controller('xyz', function() {
       var xyzVm = this;
      // Utilize xyzVm instead of _this throughout the controller
    });

Next, in your directive:

.directive('customerList',function() {
    return {
      scope: {},
      restrict:'E',
      templateUrl: 'views/templates/customersList.html',
      replace: true,
      controller: 'xyz',
      controllerAs: 'xyzVm'
    };
})

This way, your template can now access xyzVm.appointments within the repeater.

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

Encountering a 404 error while attempting to use the HTTP PUT method with Node Express

Update: Disregard my previous message - I made a small error in the Angular service. My apologies. I'm expanding my knowledge of backend development by creating a basic CMS using Angular, Node, Express, and PostgreSql. I've managed to implement ...

What sets apart Angular's $http.post from jQuery's $.post?

What is the difference between Angular's $http.post and jQuery's $.post? $http.post() vs $.post() Does $http.post() internally use $.ajax from jQuery or does it create its own XMLHttpRequest? I am currently experiencing an issue with Angular&a ...

Passing JSON information from a website to a Node.js server

<script type="text/javascript" src="data.json"></script> var mydata = JSON.parse(data); data = '[{"yer" : "Besiktas", "lat" : "41.044161", "lng" : "29.001056"},{"yer" : "Eminönü", "lat" : "41.017513", "lng" : "28.970939"},{"yer" : "Zeyt ...

Filter Observable based on object array property

I am trying to filter an Observable and only keep the stream that has a specific property value in an array of objects inside it. For example, consider this Observable: const observable = of({name: 'agency', year: '2010', job: [ ...

Dynamic modal in Vue JS with custom components

Within the news.twig file {% extends 'layouts.twig' %} {% block content %} <section class="ls section_padding_bottom_110"> <div id="cart" class="container"> <cart v-bind:materials=" ...

Using AJAX to create an interactive dropdown menu with changing options

I have been working on creating a dropdown menu using Ajax. When hovering over the navigation bar, the menu successfully triggers the Ajax function to display the dropdown options. The issue arises when attempting to navigate to another page (show_activi ...

Issue with inconsistent indentations in Pug template

Dealing with the Pug template engine has been a frustrating experience. Despite spending an entire day trying to figure it out, all I got was errors about inconsistent indentations. It's disheartening when my text ends up in the "our sponsor section" ...

Best practice for managing asynchronous calls and returns in TypeScript

I’ve recently started working on an Ionic 4 project, delving into the realms of Javascript / Typescript for the first time. Understanding async / await / promise seems to be a bit challenging for me. Here’s the scenario: In one of the pages of my app ...

Tips for selecting an <select> option value based on an URL parameter automatically

I have a 2-step form where I am successfully passing the first name in the URL from step 1 to step 2, but I am struggling to do the same for a select field. Here's an example of what I have: In the URL: ?firstname=Bob Form Field: <input type= ...

After following the official guide, I successfully installed Tailwind CSS. However, I am facing issues with utilizing the `bg-black` className for styling the background,

Following the installation guide for Tailwind CSS, I ran the command npm install -D tailwindcss postcss autoprefixer npx tailwindcss init -p. Despite this, the background className (bg-black) is not working as expected. Here are the file paths: Directory ...

405 status code returned for CORS request

Hello everyone, I need assistance with my CORS issue. I am trying to make an API request from another domain and encountering an error with the following code: var headers = { host: host, path: url + instance + '?action=reset', ...

Inquiring about JavaScript's substring method in String.prototype

let vowels = "AEIOU"; let result = vowels.substring(0, 3); document.write(result); I'm puzzled as to why the output is AEI instead of AEIO. Is this due to the indexing starting from zero in programming languages? ...

Ensuring the validity of input tags

I encountered an issue with an input tag that has a specific logic: https://codepen.io/ion-ciorba/pen/MWVWpmR In this case, I have a minimum value retrieved from the database (400), and while the logic is sound, the user experience with the component lea ...

What is the best way to incorporate Form Projection into Angular?

I have been attempting to incorporate form projection in Angular, inspired by Kara Erickson's presentation at Angular Connect in 2017, but I am encountering difficulties and errors along the way. view talk here The code provided in the slides is inco ...

Mastering the art of handling and extracting multiple parameters from URLs in AngularJS

Within this setup, there are 2 distinct views each controlled by their respective controllers. The functionality involves clicking a link in View1 to load View2 and read the parameters associated with it. However, despite attempts made, an alert is popping ...

What is the best way to organize the output of a directive?

The Directive below is what I am working with: app.directive('sidebar', function () { return { restrict: 'E', replace: true, template: '<li ng-repeat="(keymenu, valmenu) in menu"><a href="{{val ...

Highcharts JS encountered an error: x[(intermediate value)(intermediate value)(intermediate value)] is not a valid constructor

I'm in the process of creating a bar chart by fetching options from an ajax response. However, I encountered an error when passing the object to the highcharts constructor. Uncaught TypeError: x[(intermediate value)(intermediate value)(intermediate v ...

I'm having some unexpected reflections with the threejs cube camera

I'm currently experimenting with creating an object that reflects on all sides. Although I've made progress, I seem to be encountering some issues. At certain angles, I can only see partial reflections and the scale of the reflection is much larg ...

Guide on embedding PHP code into a HTML div element using JQuery

I am having trouble loading PHP code into a div tag to display the results. The code I have listed below does not seem to work for me. If anyone can offer assistance in resolving this issue, I would greatly appreciate it. Here is the code snippet: <h ...

I possess a JSON object retrieved from Drafter, and my sole interest lies in extracting the schema from it

Working with node to utilize drafter for generating a json schema for an application brings about too much unnecessary output from drafter. The generated json is extensive, but I only require a small portion of it. Here is the full output: { "element": ...