The functionality of Directive hinges on the use of a template

I am exploring a more web-component approach to using Angular. As part of this, I have developed an http-request directive with url and response attributes. The implementation is successful, but I find that my directive relies on a template unnecessarily. I would like to eliminate the template element as it seems unnecessary for the functionality of the directive. Below is the code snippet:

<div>
  <http-request url="http://jsonplaceholder.typicode.com/posts" response="items"></http-request>
  <ul>
    <li ng-repeat="item in items">{{ item.id }}</li>
  </ul>
</div>

var myApp = angular.module('myApp', []);

myApp.directive('httpRequest', ['$http', function ($http) {
return {
    restrict: 'E',
    replace: true,
    scope: {
        response: '='
    },
    template: '<input type="text" ng-model="response" style="display:none"/>',
    link: function (scope, element, attributes) {
        $http.get(attributes.url)
            .then(function (response) {
            scope.response = response.data;
        });
    }
}
}]);

Fiddle: http://jsfiddle.net/HB7LU/9558/

Answer №1

Revise your directive as follows:

myApp.directive('httpRequest', ['$http', function ($http) {
    return {
        restrict: 'E',
        replace: true,
        scope: {
            response: '='
        },
        link: function (scope, element, attributes) {
            //create response object if it doesn't exist
            scope.response = scope.response || {};
            $http.get(attributes.url)
                .then(function (response) {
                //write to items property of response object
                scope.response.items = response.data;
            });
        }
    }
}]);

Next, iterate over the response.items when using the directive:

<http-request url="http://jsonplaceholder.typicode.com/posts" response="response">
</http-request>
<ul>
    <li ng-repeat="item in response.items">{{ item.id }}</li>
</ul>

Updated example.

The original method (with the template inside the directive) was replacing the reference within the isolate scope with the $http data. This resulted in being bound to ng-model="response", which was then updated through two-way binding. Additionally, you are utilizing an outdated version of Angular. More recent versions eliminate the need for this workaround by simply removing the template.

Recent Angular example.

Update:

If you prefer not to bind to an items property, you can modify your directive like so (utilizing the $parse service to set the value on scope). This approach is compatible with older versions of Angular as well:

myApp.directive('httpRequest', ['$http', '$parse', function ($http, $parse) {
    return {
        restrict: 'E',
        replace: true,
        link: function (scope, element, attributes) {
            //use $parse to assign this value to scope
            var responseSetter = $parse(attributes.response).assign;
            $http.get(attributes.url)
                .then(function (response) {
                //call the "setter" against scope with the data
                responseSetter(scope, response.data);
            });
        }
    }
}]);

Demo.

Answer №2

Your directive doesn't necessarily need a template, as it is simply responsible for managing scope variables to represent the state of the request and reacting to the response status and data.

If you're interested, take a look at https://github.com/coding-js/directives/tree/solutions/datasource which was shared during a recent JavaScript meetup I helped organize.

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 it possible to utilize AJAXToolKit and Jquery on a single webpage?

Is it possible to utilize both AJAXToolKit and jQuery on a single page? For example, let's say we have ScriptManager in the same page along with including ...

I am experiencing issues with the ng-dropdown-multiselect library and it is not functioning

Check out this awesome library for creating dropdown menus using angularjs and twitter-bootstrap-3 at: . I am trying to implement the examples provided. In my html, I have: <div ng-dropdown-multiselect="" options="stringData" selected-model="stringMod ...

Prevent the submit button from being clicked again after processing PHP code and submitting the form (Using AJAX for

I've set up a voting form with submit buttons on a webpage. The form and PHP code work fine, and each time someone clicks the vote button for a specific option, it gets counted by 1. However, the issue is that users can spam the buttons since there i ...

Tips for appending the id of an active element to a URL

My goal was to include the id value of the active element in a URL and then redirect to that URL with a button click. HTML <div class="icon" tabindex="0" id="company"> <img src="company.png"> </div> <button type="submit" onclick= ...

obtain data from JSON using JavaScript

Greetings! I am dealing with a JSON output that looks like this: "{ \"max_output_watts\": 150, \"frame_length_inches\": \"62.20\", \"frame_width_inches\": \"31.81\" }" I am using it in a functi ...

Leveraging React hooks to combine an array and an object within an array

Struggling to incorporate an array and an object into another array. This is the setup in my constructor: const [dashboard, setDashboard] = useState({ loading: true, data: [], address: '' }) This is how I envision the final data structure: { ...

The checkbox generated from the JSON is failing to display the alert when it is clicked

I have been trying to pass checkbox input from JSON into HTML. When I click on the checkbox, an alert should pop up, but it's not working. Here is my code: $aroundCheck='<div id="content">'; foreach ($checkLocation as $checkLocation) ...

Encountering a problem with npm installation during the setup of node-sass

While attempting to run the npm install command, I encountered an error during the installation of node-sass. https://i.stack.imgur.com/qcDaA.png https://i.stack.imgur.com/YxDi2.png Here is my package.json file: { "name": "XXXXX", ...

Exploring asynchronous data handling in AngularJS using promises

Currently, I am working on a single page application using angularJS and encountering some difficulties in storing asynchronous data. In simple terms, I have a service that contains my data models which are returned as promises (as they can be updated asy ...

Avoid reloading the page in PHP when the browser back button is clicked

I've built an HTML form where the values are passed to a second page using POST method. On the second page, I have an edit button that, when clicked, redirects back to the HTML form page with the user's typed values. However, my dilemma is figuri ...

Stagnant className in map persisting despite changes being made

I am in the process of updating my react className based on changes to the active status within the sites variable, which is iterated over with a map function. The issue I'm facing is that the 'inactive' className persists even when the act ...

Exploring the capabilities of dynamic pathname routing in Next.js

Consider this scenario: there is a path that reaches me as /example/123 and I must redirect it to /otherExample/123. My code utilizes next/router, extracting the URL from router.asPath. if(router.asPath == '/example/123') { Router.push(' ...

Invoke a function using the output of a different function

There is a function whose name is stored in the value of another function, and I need to invoke this function using the other one. The function I need to call is popup() random() = 'popup()' if ($.cookie('optin-page')) { } I attemp ...

Limiting page entry with passport.js and express middleware

My server is set up to authenticate user login. I have successfully redirected users to the success page after authentication (and back to the login page if it fails). However, I am facing an issue with using my own express middleware to restrict access fo ...

Is there a way to repurpose a function to work with both ids and classes?

My current code is affecting all elements instead of just the intended one. I've experimented with classes and ids, ruling out those as potential issues. I'm hoping for my JavaScript to target only the selected element, not all of them. Check ou ...

Setting the CSS position to fixed for a dynamically generated canvas using JavaScript

My goal is to fix the position style of the canvas using JavaScript in order to eliminate scroll bars. Interestingly, I can easily change the style using Chrome Inspector with no issues, but when it comes to implementing it through JS, I face difficulties. ...

What could be causing my Vue.js sorting array script to malfunction?

I'm encountering an issue with sorting the table by Date. The sort function used to determine the type of sorting no longer works, and I'm unsure why. html: <th @click = "sort('data_produktu')" class="date">Da ...

Updating the count property of an object using setState in React

I have an array of integers ranging from 0 to 6 as my input. My goal is to create an object that gives the count of each number in the array. edition = [6, 6, 6, 1, 1, 2]; const [groupedEdition, setGroupedEdition] = useState([{"0": 0, "1&quo ...

Elevate the value within a function and refresh the said function

I'm currently facing a challenge with this particular piece of code, let spin = new TimelineMax(); spin.to($('.particle'), 150, { rotation: 360, repeat: -1, transformOrigin: '50% 50%', ease: Linear.easeNone }); Th ...

Activate the class only on the current element

I need help with a specific functionality on my website. I have multiple sections with content and buttons, and when a button is clicked, I want to add an active class to the corresponding content section within the same row. <div id="1" class="row"> ...