Using Angular JS to update the DOM with data from a secondary service in the controller: How to do it?

Upon the page loading, my Service is activated and constructs a custom directive based on the result. After the DOM is constructed, I need to call another service and pass some data from the initial result. With the new data received, I wish to update the existing DOM accordingly. For example, Student data is initially constructed, then a new service is called with the student ID to retrieve Attendance status. Based on this data, I want to display either a Green or Red image (which already exists in the DOM but needs to be shown/hidden).

  1. What is the correct approach for achieving this?
  2. The result of the Second service is a JSON object. How can I add a class based on the ID?

First Directive

<div ng-controller="studentCtrl">
  <div ng-if="showTable">
    <student-view></student-view>
  </div>
</div>

Controller.js

angular.module('adf.widget.student')
  .controller('studentCtrl', ['$scope', 'students',
    function($scope, students) {
      //students is service.
      var data = students;
      var key;
      $scope.ids = [];
      if (data.students.length > 0) {
        $scope.students = data.students;
        for (key in $scope.students) {
          if ($scope.students[key]['id'] !== '') {
            $scope.ids.push($scope.students[key]['id']);
          }
        }
        $scope.showTable = true;
      } else {
        $scope.showTable = false;
      }
    }
  ]);

Directive.js

angular.module('adf.widget.student')
  .directive('studentView', function(dashboard) {

    return {
      restrict: 'AE',
      templateUrl: 'studentView.html',
      replace: true,
      controller: 'studentViewDirectiveCtrl'
    }
  })

studentViewDirectiveCtrl.js

angular.module('adf.widget.student')
  .controller('studentViewDirectiveCtrl', ['$scope', 'secondService',
    function($scope, secondService) {

      secondService.getStatus($scope.ids)
        .then(function(result) {
          $scope.status = result.status;
        })
        .catch(function() {
          /* error :( */
        });

    }
  ]);

studentViewTemplate.html

<div ng-repeat="std in students" class="student">
  <img class="img-responsive" src="../rv/{{std .image}}" />

  <div class="showLed">
    <!-- How do i add red/green className based on the Second Service Result -->
    <div class="led" style="position:absolute" class="red/green">
    </div>
  </div>
  ....

Result of Second Service

{
    "status": [{
        "id": 1,
        "stat": "true"
    }, {
         "id": 2,
        "stat": "false"
    }, {
        "id": 3,
        "stat": "false"
    }, {
        "id": 4,
        "stat": "true"
    }]
}

Answer №1

If you wish to achieve this, consider the following steps;

<div class="led"
     style="position:absolute"
     ng-class="{ 'green': status[std.id], 'red': !status[std.id] }">

Make sure to modify your studentViewDirectiveCtrl as shown below;

angular.module('adf.widget.student')
  .controller('studentViewDirectiveCtrl', ['$scope', 'secondService',
    function($scope, secondService) {
      function updateStatus(status) {
        var updatedMap = {};
        for (var index in status) {
          var statu = status[index];
          updatedMap[statu.id] = statu.stat === 'true' ? true : false;
        }

        return updatedMap;
      }

      secondService.getStatus($scope.ids)
        .then(function(result) {
          $scope.status = updateStatus(result.status);
        })
        .catch(function() {
            /* error :( */
        });
    }
  ]);

Answer №2

To apply the red or green class based on the return value of a functional expression, you can utilize the ng-class directive.

Template.html

<div ng-repeat="item in items" class="item">
  <img class="img-responsive" src="../rv/{{item.image}}" />

  <div class="showColor">
    <!-- Apply red/green class based on function result -->
    <div class="colorIndicator" style="position:absolute" ng-class="isValueTrue(item.id) ? 'green' : 'red'">
    </div>
  </div>
  ...

Controller.js

angular.module('myApp')
  .controller('MyCtrl', ['$scope', 'someService', '$filter',
    function($scope, someService, $filter) {
        someService.getData($scope.ids)
           .then(function(response) {
                $scope.value = response.value;
            },
            function() {
                /* error handling */
            }
        );

        // function to determine color
        $scope.isValueTrue = function(itemId) {
            $scope.itemData = $filter('filter')($scope.items, {id: itemId})[0];
            if($scope.itemData && $scope.itemData.valid == "true") {
                return true;
            }
        }

    }
]);

In this code snippet, the isValueTrue function checks if a specific value is true for an item. The corresponding class will then be displayed in the template using the ng-class directive.

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

Implementing mouse hover functionality in a VueJS component within a Laravel application

I am facing an issue with my mouse hover functionality while working on Laravel. The Vue file I am using is located in resources/js/Dashboard.vue I have attempted to replace v-on:mouseover with @mouseover but the problem persists. When I hover over the ...

Error encountered: Unable to access undefined properties while attempting to make an API call to AirTable using NextJS version 13.4

Currently in the process of learning how to use the App router with NextJS 13.4, I encountered an issue while attempting to make an external API call. Even though I am getting all the data correctly from Airtable, Next throws an error that disrupts my try ...

Link property can be added to a bindpopup polygon in Leaflet to have it open in a new tab when clicked

Is it possible to include a hyperlink in popup content on Leaflet, similar to this example? function onEachFeature(feature, layer) { idLoDat = feature.properties.IDLo; layer.bindPopup("Company name: " + feature.properties.TenCty + " ...

While the Navbar component functions properly under regular circumstances, it experiences difficulties when used in conjunction with getStaticProps

https://i.stack.imgur.com/zmnYu.pngI have been facing an issue while trying to implement getstaticprops on my page. Whenever I try to include my navbar component, the console throws an error stating that the element type is invalid. Interestingly, I am abl ...

Global AngularJS service

I am attempting to save a response variable in a global service variable. Here is my service: (function() { angular.module('employeeApp') .service('constants', constants); function constants() { this.url = &apo ...

I am facing a challenging issue with React on my console and finding it difficult to resolve

Below is the code snippet from my ShoppingList.js file, ` function ShoppingList() { return ( <ul className="lmj-plant-list"> {plantList.map(({ id, cover, title, description }) => ( <PlantItem to={"/ ...

Initialize data only when the Nuxt.js application is first loaded

Exploring the world of nuxt.js, I find myself pondering on the most efficient way to fetch data using REST api. Within my store folder, the structure is as follows: store -posts.js -categories.js -index.js Initially, I attempted to set the da ...

Is there an issue with the precedence of jison rules?

I've been stuck for hours trying to solve what seems like a simple problem but I just can't figure it out :/ I'm working on defining a small javascript-like language in jison. The issue I'm facing is that both the Parameter rule and th ...

borders in motion

I am currently working with this jQuery code. //this is the main javascript $(document).ready(function(){ $('nav.menu a').hover( function () { $('nav.menu').find(".current_item").removeClass("current_item"); ...

Guide to creating a cryptosystem using a Synchronous Stream Cipher with Vue js

I am currently working with a pseudo-random number generator that creates binary numbers using a user-supplied polynomial and the LFSR method. To enhance the process, I need to convert a loaded file into binary format so that I can apply the XOR operatio ...

Can Google Charts columns be customized with different colors?

Is it possible to modify the colors of both columns in Google's material column chart? Here is the code I am using for options: var options = { chart: { title: 'Event Posting', subtitle: 'Kairos event p ...

Accessing an unregistered member's length property in JavaScript array

I stumbled upon this unique code snippet that effectively maintains both forward and reverse references within an array: var arr = []; arr[arr['A'] = 0] = 'A'; arr[arr['B'] = 1] = 'B'; // When running on a node int ...

Creating independent Javascript applications and HTML5 canvas games, optimized for V8 or tailored to the specific browser for optimal performance

Instead of solely targeting Chrome users due to browser performance issues, I am exploring alternative options to create an executable version of a canvas game. Is there a way to integrate v8 for non-Chrome users? Perhaps a web "wrapper" similar to Flash&a ...

Developing an Angular application that triggers a nested request in a Node/Express backend

Currently, I am working on a project that involves AngularJS and NodeJS/Express. Everything is functioning properly with the AngularJS resources, except for a custom action I added. This custom action seems to be causing an issue where req.params and req.b ...

Calculating the combined cost of items in the shopping cart

I encountered a small problem while working on my project. I'm trying to calculate the total price of all items in the cart by summing them up, but my mind is drawing a blank at the moment. Below is the code snippet I am currently using: const { ca ...

Using Javascript to map an array with objects from a different array and then returning the computed array

I'm struggling to solve a seemingly simple issue. I have an array that looks like this: Array 1: [ { "id": 1, "date": "2019-03-27", "time": 1, "max_tasks": 3, "reservations": [ 5, 2 ...

What is the best way to update only a portion of a nested schema in mongoose?

UPDATE: Through numerous trials, I finally discovered a successful method that converts any object into a format that mongoose can interpret. Take a look at the solution provided here: const updateNestedObjectParser = (nestedUpdateObject) => { cons ...

JavaScript: Display all global variables on Internet Explorer

Is there a way to retrieve the instance name of my class without passing it as a parameter? I have tried looping through all global objects and comparing them with the this pointer. This method works in Chrome and Firefox, but not in Internet Explo ...

Is it possible to asynchronously retrieve the information from the HTTP request body in a Node.js environment?

I am trying to send an HTTP POST request to a node.js HTTP server that is running locally. My goal is to extract the JSON object from the HTTP body and utilize the data it contains for server-side operations. Below is the client application responsible fo ...

Retrieve the concealed division element's HTML content along with its formatting

Help needed with appending a hidden div with its styles intact. Despite using the code provided below, the appended div does not retain its styles. Any suggestions for an alternative method? var warningMessage = $('#warningDiv').html() fun ...