How to Retrieve JSON Response in Link Function within AngularJS Directive

I have decided to implement a chart library called Plotly in my project. To ensure reusability, I am creating a directive in AngularJS that will allow me to easily integrate the library in the future.

The directive will receive an object as input to create the graph. This object is fetched through an API call. Here's the code snippet:

CONTROLLER:

angular.module("app").controller("appDetailsController", 
    ['$scope', '$http', function($scope, $http) {


  $scope.graphData = {}

  $http.get('/api/analytics/24').then(function(data) {
    console.log('Loaded analytics data:', data);
    $scope.graphData = data.data
  })

}])

DIRECTIVE:

angular.module("app").directive("timelineGraph", function() {
    return {
        restrict: "E",
        scope: {
            data: "="
        },
        link: function(scope, element, attr) {
            console.log("scope data:", scope, scope.data)
        }
    }
})

HTML:

<timeline-graph data="graphData"></timeline-graph>

When inspecting the "scope" inside the link function, I noticed that the data object is only populated after the API call. To handle this, I added a $watch function like this:

scope.$watch('data', function(data) {
   if(data)
     console.log('data changed:', data)
})

However, I am curious if there is a more efficient way to handle this scenario without relying heavily on the $watch function. Any suggestions would be appreciated.

Answer №1

It's important to note that not all of your code needs to be placed within the watch function:

// Inside your directive
scope.$watch('data', function(data) {
  if (data) {
    dataUpdated();
  }
});

All you have to do is call a specific function to start the necessary code to update the directive

// Also within your directive
function dataUpdated() {
  // Perform necessary actions
}

Other than that, it looks like you're making good progress.

Answer №2

Upon conducting some investigation, it is evident that your code functions as expected (please refer to the code snippet below). The user interface refreshes accordingly when the data is modified, indicating no issues. As suggested by @JoelCDoyle, it would be beneficial to encapsulate your code within a distinct function and invoke it within the $watch.

angular.module("app", [])
.controller("appDetailsController", 
['$scope', '$http', '$timeout', function($scope, $http, $timeout) {

  $scope.graphData = [];

  $scope.init = function(){
    $http.get('https://jsonplaceholder.typicode.com/users')
    .then(function(resp) {
      $scope.graphData = resp.data;
    })
  }  
}])
.directive("timelineGraph", function() {
return {
restrict: "E",
scope: {
data: "="
},
template: '<div>"{{data}}"</div>',
link: function(scope, element, attr) {
console.log("scope data:", scope.data)
}
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <div ng-controller="appDetailsController" ng-init="init()">
    <timeline-graph data-data="graphData">  </timeline-graph>
  </div>
</div>

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

Each time forEach is called, it increments the previous result by 1

My service returns a response containing the following data: {"id":157336,"results":[ {"id":"53db3c790e0a26189a000d09","iso_639_1":"en","key":"ePbKGoIGAXY","name":"Trailer 3","site":"YouTube","size":1080,"type":"Trailer"}, {"id":"550df44b925141355 ...

Retrieve the text label from the parent option group

Below is the HTML code snippet: <select id="categoryg"> <optgroup label="Main" value="binding"> <optgroup label="Sub" value="binding"> <option value="46&quo ...

Check the validity of multiple selection groups using JavaScript

Here is the link to my JS Fiddle: http://jsfiddle.net/m4tyC/ I am working with multiple select tags and need to validate them upon submission. For example, at least one of size1, color1, or Qty1 must be selected in the first group. If one item is selected ...

Exploring the possibilities of implementing Undo and Redo features in freehand drawing with Reactjs on

After attempting to create a Freehand drawing using HTML5 canvas with React, my next step is to incorporate an undo and redo functionality when the corresponding buttons are clicked. I would greatly appreciate any assistance provided. function App(props) ...

Unraveling the mystery: How does JavaScript interpret the colon?

I have a quick question: When I type abc:xyz:123 in my GoogleChrome browser console, it evaluates to 123. How does JavaScript interpret the : symbol in this scenario? ...

What are the typical situations in which Node.js is commonly used?

Do you believe that a majority of node.js users primarily utilize npm? What do you think are the most prevalent use cases for node.js apart from npm? ...

Executing a function in a controller from a template only when a certain variable is true

Here is a row that I have: <a class="btn btn-default btn-xs" ng-click="list.showReview = list.showReview == $index ? -1 : $index; getValues(object.Id); "><i class=" glyphicon glyphicon-list-alt"></i></a> I am looking to only call ...

Using JQuery to modify several background images in unison

I have a CSS code that uses 8 images to create a frame: background-image: url(images/blue/tl.png), url(images/blue/tr.png), url(images/blue/bl.png), url(images/blue/br.png), url(images/blue/t.png),url(images/blue/b.png),url(images/blue/l.png),url(images/b ...

Can VueJS Computed handle multiple filters at once?

I am encountering an issue with this code - when I attempt to add another filter inside the computed section, it doesn't work. However, if I remove the additional filter, the code functions correctly. My goal is to have both company and product searc ...

Adjust picture based on the MaterialUI slider's value

I want to incorporate a discrete Slider component from Material UI into my React web app. The goal is to have the user change a picture every time they adjust the slider value, with the new image displayed in a specific div. I am wondering how I can achiev ...

Run a JavaScript function once the AJAX content has been successfully added to the element

I have a JavaScript AJAX function that retrieves content and adds it to an HTML element named content_holder. After the content is updated with the AJAX request, I want to trigger a function. I've attempted to include a <script> tag within the a ...

Extract information from an HTML table into PHP

I have an HTML table that is generated dynamically and I am looking to extract the data from it using the POST method. Is there a way to accomplish this? Are there any alternative methods you would suggest for achieving this goal? Below is a basic example ...

When an HTML element is deleted, its events are not being removed as expected

I currently have events bound in my backbone view. sampleView = Backbone.View.extend({ events: { "click .sum": "sumButtonFunc", "click .diff": "diffButtonFunc" } sumButtonFunc: function(){ console.log("sum called") ...

Managing the length of a PHP session

As a beginner in web development, I have been trying to figure out how to limit session time in PHP. I have researched on Stackoverflow but haven't found a suitable solution yet. Some suggestions like using cookies, AJAX communication, and static PHP ...

How can a function be invoked in a child component from a parent component?

I am facing a challenge where I need to trigger the function showExtraBlogposts() in Blogpostreader.js upon clicking on a button rendered in Blog.js. Initially, I attempted to call it using onClick={Blogpostreader.showExtraBlogposts()} but it returned an ...

Is there a way to incorporate the image that was uploaded from the server onto an HTML page without using the file extension?

$('#userInfoPhoto').html(function () { return '<img src="../uploads/' + thisUserObject.profileimage + '" alt = "userphoto" style="width:250px; height:250px"/>' }); This script is essential for rendering images on th ...

Mastering JavaScript Loops

Looking to create an endless loop of links that never stop? I need assistance achieving this. setTimeout(linkToGoogle, 5000); function linkToGoogle() { document.getElementById('myAnchor').innerHTML="Visit Google"; document.getElementById(&a ...

Dealing with Error TS2769 in Visual Studio Code when passing props to a custom component in Vue 2 with Typescript

I've encountered an issue with a Vue JS component that involves passing a custom prop. I am utilizing the Vue Options API without utilizing the class component syntax. Whenever I pass ANY prop to my custom component the-header, I receive an error sta ...

What is the process for submitting a form in Laravel 5 with ajax?

Struggling with understanding how to create an ajax post in Laravel. I would like to display errors using jQuery after validation, but I'm unsure about accessing the object sent to my controller and what needs to be 'returned' in the control ...

Tips for maintaining the nested collapsible table row within the main table row in a React MUI table

I am working on implementing a Material UI (MUI) table that includes collapsible table rows. The challenge I am facing is maintaining consistent border and background colors across all the rows, even when some are collapsed. Currently, the separate rows ar ...