Currently waiting for the $resolved property of the AngularJs service

Here's a straightforward issue with what I hope is an equally simple solution.

I've set up multiple services for handling CRUD operations with tags.

myApp.factory('GetTags', ['$resource', function ($resource) {
    return $resource('/myApp/API/Service/GetTagList', {}, {
        query: { method: 'GET', params: { groupId: 'groupId' }, }, isArray: true,
    });
}]);

myApp.factory('GetTag', ['$resource', function ($resource) {
    return $resource('/myApp/API/Service/GetTag', {}, {
        query: { method: 'GET', params: { tagId: 'tagId' }, }, isArray: true,
    });
}]);

myApp.factory('SaveTag', ['$resource', function ($resource) {
    return $resource('/myApp/API/Service/CreateTag', {}, {
        query: { method: 'POST', params: {/*createObj*/}, }, isArray: true,
    });
}]);

myApp.factory('UpdateTag', ['$resource', function ($resource) {
    return $resource('/myApp/API/Service/UpdateTag', {}, {
        query: { method: 'POST', params: {/*updateObj*/}, }, isArray: true,
    });
}]);

When I reach my controller, I want to achieve something like this within my tags function:

myApp.controller('myCtrl', ['$scope', '$routeParams', 'GetTags', 'GetTag', 'SaveTag', function ($scope, $routeParams, GetTags, GetTag, SaveTag) {
    ...
    // The aim of this function is to maintain a local copy 
    // of the tags collection in memory that resembles the database
    // while also adding selected tags to the forms object
    // e.g. myForm = {... Tags: [], ...}
    $scope.addtag = function (tag, subTag){
        ...
        if (!($scope.tags.length > 0)) {
            // Skip checking and simply add the tag
            SaveTag.save({ Name: tag, Desc: "", ParentId: null, GroupId: 12, }, function (data) {
                console.log('save tag: ', data);
                //todo: should wait for data of save operation to comeback
                //      before moving on to requesting a full object
                GetTag.get({ tagId: data.Id, groupId: 12, }, function (data) {
                    console.log(' get tag: ', data);
                    tagObj = data.tag;
                });
            });
            // Push newly created tag into tags collection
            $scope.tags.push(tagObj);
        ...
    };
    ...
});

I omitted some detailed information from my controller and function in question but essentially, I use save followed by get due to the tag + subTag scenario. I avoided complicating the logic by passing a complex object to the server. For instance, creating a tag followed by a

subTag</code would look like this in JavaScript:</p>
<pre><code>...
// Skip checking and directly add tag and subTag
SaveTag.save({ Name: tag, Desc: "", ParentId: null, GroupId: 12, }, function (data) {
    //todo: should wait for data of save operation to comeback
    //      before moving on to requesting a full object
    GetTag.get({ tagId: data.Id, groupId: 12, }, function (data) {
        tagObj = data.tag;
    });
});
// Push newly created tag into tags collection
$scope.tags.push(tagObj);

SaveTag.save({ Name: subTag, Desc: "", ParentId: tagObj.ParentId, GroupId: 12, }, function (data) {
    //todo: should wait for data of save operation to comeback
    //      before moving on to requesting a full object
    GetTag.get({ tagId: data.Id, groupId: 12, }, function (data) {
        tagObj = data.tag;
    });
});
// Push newly created sub tag into tags collection
//todo: find parent index
$scope.tags[parent_index]["Elements"].push(tagObj);
...

If you're wondering, yes, returning the full object from the save operation is something I might do soon. It's best to minimize the number of asynchronous calls for overall performance reasons.

However, I have a few queries at the moment:

  1. Currently, I have four separate services declared as per Angular documentation. It would be more efficient to consolidate them into a single factory with multiple functions. Can someone guide me in the right direction here please?
  2. Is there a way to pause and wait for the data.$resolved property to become true after calling the save service so that I can then call the get service with the returned value? Or is there an alternative approach?
  3. I am exploring Angular Documentation's $q to see if I can utilize anything from there.

In case you're curious, I've encountered examples where people used the resolve property with $routeProvider, but my scenario involves real-time interactions during user actions.

Any assistance or advice is greatly appreciated.

References:

  1. AngularJS Docs - $q
  2. Informative explanation and examples - Using and chaining promises in AngularJS
  3. AngularJS Docs - $resource (last example demonstrates use of $promise)

Update:

It appears my instinct was correct. While I haven't figured it out yet, I believe the answer lies within utilizing $q and chaining promises. Now I just need to make it work.

Answer №1

It's funny how I always end up finding the solution to my own questions.

Latest Update:

After some serious thinking and troubleshooting, I cracked the code:

// stop verifying and simply insert tag
SaveTag.save({ Name: tag, Desc: "", ParentId: null, GroupId: 12, }).$promise.then(function (data) {
    console.log('save tag: ', data);
    return data;
}).then(function (data) {
    console.log('data: ', data.Id);
    GetTag.get({ tagId: data.Id, groupId: 12, }).$promise.then(function (data) {
        console.log(' get tag: ', data);
        return data;
    }).then(function (data) {
        console.log('data: ', data.tag);
        $scope.tags.push(data.tag);
        tagObj = data.tag;
        //todo: check for duplicate records
        //      because repeater will complain and
        //      it's pointless to have duplicate tags
        //      on an item to begin with
        $scope.myForm.Tags.push(tagObj);
    });
});

Take note of the $promise used after every service call. This allows me to chain additional logic using .then().

In the end, all I did was tweak the way I interact with my services. Simple as that.

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

Getting the response data from an XMLHttpRequest - Full guide with screenshots

Currently, I am working with autocomplete jQueryUI and have this code snippet: .autocomplete({ source: function( request, response ) { var results = $.getJSON( url, { term: extractLast( request.term ) }, response ); console.log(results); ...

Is there a way to include a variable in the URL for an AJAX call?

When working with a PHP function that requires an ID and adding a variable to the Ajax URL, the following code snippet can be helpful: PHP Code: function get_json_selected($purpose) { $ids = explode(",", $this->input->post("ids")); ...

Displaying the combined total for each date

My goal is to calculate the total for each department without duplicates ( which is currently working ) and display all results based on the selected date. I intend to select a date using md-datepicker and then only display the total task time where the d ...

Building a Mongoose Schema with an Array of Object IDs: A Step-by-Step Guide

I created a user schema using mongoose: var userSchema = mongoose.Schema({ email: { type: String, required: true, unique: true}, password: { type: String, required: true}, name: { first: { type: String, required: true, trim ...

Tips for effectively utilizing Formik's handleChange method multiple times to update a single value

Utilizing Material-UI along with Formik, I am trying to enable two input fields to modify a single value. The scenario involves having a TextField and a Slider where both inputs should have the ability to change the value for period. When assigning the sam ...

One way to incorporate if / else if statements into a function within a Class component is by using conditional logic in React alongside Node and Express

I'm looking to refactor my code and extract the if/else if statements for error handling out of the component. How can I export this logic to another file and then import it back into my main component? Here's an example of the code: // PASSWOR ...

Sending data from TextBox as json format

JavaScript Code: var latitude = document.getElementById("<%=txt_Lat.ClientID %>").value; var longitude = document.getElementById("<%=txt_Long.ClientID %>").value; var jsonData = {latitude: latitude, longitude: longitude}; var jsonString = JSO ...

The functionality of Webdriver.waitUntil is not meeting the expected outcomes

I'm currently utilizing webdriverio version 4.5: ./node_modules/.bin/wdio -v v4.5.2 In my scenario, I am in need of waiting for the existence of a specific element and handling the situation if it doesn't exist. Here is an example code snippet ...

Occasionally, the map may take a moment to fully load

Update: Resolving the issue involved directly calling these two methods on the map object: leafletData.getMap().then(function(map) { map.invalidateSize(); map._onResize(); }); Encountering a minor yet bothersome problem with the Leaflet directive ...

Steps to creating an Ajax JQuery in WordPress with promises

Currently, I am in the process of developing a custom Wordpress Google Maps plugin. This plugin fetches locations from a database using Ajax and returns an XML file that is then handled by a Javascript script to display them on a Google Map. Everything is ...

Error: Syntax mishap detected - Oh dear

Recently, I've been developing a small slideshow / public display for a client using the HTML5 Rock's Slideshow code. Everything was going smoothly until I encountered a DOM Exception 12 - an error related to CSS selectors. Strangely, I couldn&ap ...

Incorporating middleware to handle 404 errors in Express

scenario app.use("/api/tobaccos", tobaccos); app.use(function(err, req, res, next) { console.error(err.message); }); API details: router.get("/:id", async (req, res) => { console.log("GET TOBACCO:" + req.params.id); ...

Preventing the occurrence of empty nested arrays within the state

I am currently working on a React Redux application where I am adding movies and including images as a nested array within my object. Here is what my state looks like after adding an item: { movies: [ { "title": "asda", "director": "as ...

Extension for capturing videos on Chrome or Firefox

I am interested in developing a Chrome or Firefox extension that can capture video from a window or tab. My goal is to record full screen videos, such as those on YouTube, for offline viewing similar to a DVR for online content. Creating an extension see ...

Having issues with regEX functionality in an Angular form

I need to validate a phone number using regEX. My criteria is as follows: 10 digits alpha/numeric, where an Alpha CHAR is in the 4th position (excluding hyphens). For example: 586R410056  NNN ANN NNNN  (NNN) ANN NNNN  NNN-ANN-NNNN  (NNN) AN ...

Error TS2322: Type 'boolean' cannot be assigned to type 'undefined'. What is the best approach for dynamically assigning optional properties?

I am currently working on defining an interface named ParsedArguments to assign properties to an object, and here is what it looks like: import {Rules} from "../Rules/types/Rules"; export interface ParsedArguments { //other props //... ...

I prefer not to have my preceding component re-rendered in React

I'm currently working on developing a user interface for a search engine using elasticsearch within React. One issue I'm facing is with the Pagination technique - when a user clicks on a result and then navigates back to the list of results, it r ...

Prevent the onClick function of the outer div from being triggered by clicking on the inner div

Similar Question: Stop parent container click event from firing when hyperlink clicked My issue is <div onClick="someJScode();"> ... <div></div> ... </div> I need to prevent someJScode() from executing when the inner di ...

Order Typescript by Segment / Category

Suppose we start with this original array of objects: {vendor:"vendor1", item:"item1", price:1100, rank:0}, {vendor:"vendor1", item:"item2",price:3200, rank:0}, {vendor:"vendor1", item:"item3", price:1100, rank:0}, {vendor:"vendor2", item:"item1", price: ...

Utilize JQuery to identify and select every parent element, then retrieve the height of the first child element and adjust the height of the

Recently, I developed a PHP script that pulls news and case posts from a database. The HTML structure used for displaying these posts is as follows: <a href='/post/placeholder'> <div class='col nopadding col12-12 counter'> ...