Leveraging Promises with Angular $resource

How can I implement promises with $resource in my Angular service?

Here is a snippet from my service:

     app.service("friendService",function( $resource, $q ) {

        // Define public API functions.
        return({
            addFriend: addFriend,
            updateFriend: updateFriend,
            getFriends: getFriends,
            removeFriend: removeFriend
        });

        function updateFriend( friend ) {

            var postData = { 
                id: friend.id,
                name: friend.name
            };

            var request = $resource("api/update.php", null,{
                update: { 
                    method:'PUT',
                    data:postData
                }
            });


            return( request.$promise.then( handleSuccess, handleError ) );
        }

However, I am encountering an error message:

TypeError: request.$promise is undefined

Can someone suggest the correct way to utilize promises with $resource in AngularJS? Thank you.

Answer №1

Switch it up to

return request.update().$promise.then(handleSuccess, handleError);

Instead of

return( request.$promise.then( handleSuccess, handleError ) );

Although, it's worth noting that using $resource in this manner is not very efficient and does not fully utilize its capabilities. It would be more beneficial to use $http instead.

Answer №2

It's beneficial to streamline your service to embody the essence of $resource.

app.factory('friendService', [ '$resource', function($resource) {
    return $resource('/api/friends/:id', null, {
        'update' : {
            method : 'PUT'
        }
    });
} ]);

This approach automatically generates the following endpoints (which is one of the key advantages of $resource):

{ 'get':    {method:'GET'},
  'save':   {method:'POST'},
  'query':  {method:'GET', isArray:true},
  'remove': {method:'DELETE'},
  'delete': {method:'DELETE'}
};

Here are some examples of how to use it:

friendService.query(success, error); // GET /friends
friendService.get({ id : "exampleId" }, success, error); // GET /friends/exampleId
friendService.save({/* no params */}, friendObjectWithId, success, error); // POST /friends/idTakenFromObject
friendService.delete({ id : "exampleId" }, {}, success, error); // DELETE /friends/exampleId
friendService.update({/* no params */}, friendObjectWithId, success, error); // PUT /friends/idTakenFromObject

According to this line from the documentation, you can omit using $promise to define the callbacks:

non-GET "class" actions: Resource.action([parameters], postData, [success], [error])

So, you can simply execute something like this:

friendService.update({}, friendObject, successHandler, errorHandler)

Answer №3

In brief:

Your confusion seems to stem from misconceptions about the $resource in comparison to $http.

$resource acts as a wrapper around $http to facilitate Object Oriented CRUD interactions with a RESTful api. (The official documentation provides detailed explanations and examples)

Given the nature of your URL, it appears that a REST api may not be in use, making it more appropriate to utilize the $http service rather than $resource.

Here is a functional demo for reference.


Resource Usage and REST API Integration

In the context of Angular, a resource corresponds to a REST resource, necessitating alignment with REST principles for effective implementation. To illustrate, consider a hypothetical "Friend" scenario... (I will adjust your URLs to align more closely with REST API standards)

API Conceptualization

Envision the following REST+CRUD compliant setup (for a Friend resource)

Resource            URI             Supported Methods
Friend Collection   api/friend      GET, POST
Friend              api/friend/:id  GET, PUT

The primary tenet here is that each Resource is uniquely identified by a URI (a fundamental aspect of URI: -> Uniform Resource Identifier) with the HTTP Method (Verb) specifying the operation conducted on the Resource.

While REST encompasses broader concepts, I recommend exploring this SO POST or this insightful article or Roy Fielding's dissertation (the REST progenitor) for comprehensive understanding.


URL Formatting

URL structuring can trigger heated debates, with interesting perspectives outlined in this SO Post and an article by Roy Fielding addressing the topic. In essence, REST does not mandate clean URLs; the focus lies on being hypertext-driven. This dictates that given a starting point (URL), the API should be self-explanatory, allowing clients to "discover" resources autonomously, with resource types specified by media-types. This approach ensures that if a URL changes, the API remains functional without disruptions.

Hence, the following structures are acceptable:

Home                 /
Friend Collection    /foo
Friend Resource 1    /bar
Friend Resource 2    /baz

As well as:

Home                index.php
Friend Collection   index.php?q=api/friend
Friend Resource 1   index.php?q=api/friend/1
Friend Resource 2   index.php?q=api/friend/2

Or with mod_reqrite for "clean URLs":

Home                /
Friend Collection   /api/friend
Friend Resource 1   /api/friend/1
Friend Resource 2   /api/friend/1

Alternate variations:

Home                /index.php
Friend Collection   /friend.php
Friend Resource 1   /friend_1.php
Friend Resource 2   /friend_2.php

While servers are not mandated to follow a particular pattern, adhering to a structure, especially for SEO purposes or human comprehension, is recommended. The last example's reliance on individual scripts for each resource can complicate development (though not violating REST principles, it may defy basic programming rules like DRY...)

Angular-resource does have preferences regarding URL structure, although not obligatory...

For your specific inquiry, mod_rewrite is required to align with the aforementioned example. However, REST compliance can be achieved without mod_rewrite.


Implementing angular-resource Module

With a defined API scheme adhering to REST+CRUD principles, the angular-resource module can be efficiently leveraged.

We can create a client-side representation (interface) for "Friend".

//Custom actions
var actions = {
    update: {
        method: 'PUT'
    }
}

var friendUrl = "/api/friend/:id"; // typically obtained by reviewing the API, often the parent collection
var Friend = $resource(friendUrl, {id: '@id'}, actions);

To retrieve a friend, a GET request (with the specified id) is initiated;

Friend.get({id: 1}).$promise.then(
    function (response) {
        //console.log(response);
    }
);

DELETE and PUT requests (such as the custom action update) follow a similar principle. Additionally, $resource facilitates collection retrieval through the query method. Utilize this to fetch the friends collection.

Note the usage of a hardcoded URL for simplicity

Answer №4

In order to make a request, you must first establish your endpoint. Remember to execute a method on it, such as request.post({id: 1}).$promise; or

request.update({term: 'sample'}).$promise;

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

Error with REST service and browser history in ReactJS

I am currently developing my first Java application, which is a REST service built with Spring Boot. It utilizes technologies such as WEB, REST, JPA, Thymeleaf, and MySQL. The API is fully functional, but I wanted to enhance it with a user interface. After ...

Obtaining the referring URL after being redirected from one webpage to another

I have multiple pages redirecting to dev.php using a PHP header. I am curious about the source of the redirection. <?php header(Location: dev.php); ?> I attempted to use <?php print "You entered using a link on ".$_SERVER["HTTP_REFERER"]; ?> ...

Enhancing user experience by implementing AJAX in a contact form to eliminate the need for page

I have read numerous questions on this topic and have compiled the code I currently have from various responses. Unfortunately, despite my efforts, I am unable to make it work and I cannot identify the reason behind this issue. Below is the HTML form str ...

Retrieve combination values through an AJAX request using ExtJS

My UI is developed using ExtJS, and I have a specific set of tasks that need to be executed when the page loads: Initiate an ajax call to the server to fetch a HashMap. Create a combobox within the main Panel on the page. var combo = Ext.create(' ...

Saving table sorting in Redux with Ant Design Table

I am currently working with Antd Version 4.2.2 in my ReactJS project. Specifically, I am utilizing the Ant Design < Table /> component. My goal is to save the sorting order that is applied to the columns into Redux state. Here is my current approa ...

How do I store the result of an Ajax request as a variable in a different function within a React component?

One of the challenges I'm facing involves making an ajax call that retrieves a list of movies, and then running another function with a separate ajax call to fetch the genre names. Since the first call only provides the genre IDs, I need to match each ...

Enhancing vanilla HTML elements with custom props using React

const handleSelectChange = (e) => { console.log(e.target.getAttribute('id')); }; return ( <div> <select onChange={(e) => handleSelectChange(e)}> <option value="1-10" id=&qu ...

Display a division in C# MVC 4 when a boolean value is true by using @Html.DropDownList

I have multiple divs stacked on top of each other, and I want another div to appear when a certain value is selected. I'm familiar with using JavaScript for this task, but how can I achieve it using Razor? Below is a snippet of my code: <div id=" ...

Challenges with handling multiple concurrent AJAX requests in jQuery

The challenge here is that the application needs to make multiple requests to a web service using $.ajax, but the number of times these requests need to be made depends on the user. Due to this dynamic nature, it appears that using $.when might not be suit ...

Delay the fading in of an element using jQuery

Is there a way to remove the pause between the images in my JavaScript/jQuery slideshow when fading in and out? I attempted using a small delay, but it still didn't eliminate the blank space. Any suggestions? Check out the code on jsfiddle: https://j ...

Is it possible to execute a function upon exiting my Node application?

Currently, I'm developing a project for my school using Node.js on a Raspberry Pi. The script I have created will be running for extended periods of time to control LEDs. Is there a method that allows me to execute a function upon exiting the program ...

What is the purpose of the 'onClassExtended' function in Extjs 6 for class definition?

Ext.define('Algorithm.data.Simulated', { needs: [ //.... ], onClassExtended: function(obj, info) { // .... } }) I came across this code snippet but couldn't locate any official documentation for it on Sencha ...

Adjust parent div size based on image size increase

I am currently facing a situation where I have a page displaying an image, but sometimes it appears too small. In order to make the image larger, I have utilized CSS Transform and it is working well. However, the issue lies in the fact that the parent DIV ...

Integration issue: React.js is failing to render within a Django project

I have been working on a project where React is not rendering anything on Django localhost. index.html <!DOCTYPE html> <html lang="en"> <head></head> <body> <div id="App"> <!---all will b ...

Creating a personalized directive for post-submit data validation in AngularJS

Looking to implement a custom directive for data validation post web service call. Stumbled upon a blog example; however, it's triggering the web service call on every value change in the form! Desire for the custom directive to only activate upon us ...

Is it possible to convert a blob to an image file using the FileReader in HTML

client side code <head> <script> var reader = new FileReader(); var objVal; var image = new Image(); reader.onload = function(e) { document.getElementById('propertyImg').setAttribute('src', e.target.result); }; fun ...

Implementing a validator based on the operator selection in react-querybuilder

Is it possible to add validators to fields that are only active when using the like operator? For example, if the like or unlike operators are used in the phoneNumber field without the % sign, it should be invalid. If the = operator is used, the % sign sho ...

Validating an Element Directive in AngularJS: A Step-by-Step Guide

I have developed a directive for handling numbers function numberInputDirective() { return { restrict: 'E', scope: { model: '=', disabled: '=?', decimals: ...

Utilizing shared functions defined across different controllers

Can I utilize the code within these controllers for other purposes? .controller('GenericController', ['$scope', '$controller', '$rootScope', '$dialogs', '$state', '$http', '$modal& ...

Creating a Sudoku game board using underscore templates

Currently, I am in the process of constructing a Sudoku board using underscores templating. However, I have hit a roadblock when it comes to tackling the mathematical aspects necessary for deriving the table structure. My approach involves utilizing a 1d ...