Can the angularjs cached resource method be utilized within a filter?

In my current project, there is a property in the scope that contains an ID for an external object. Additionally, I have implemented a filter that takes this ID and expands it into a complete object using the following code:

{{ typeId | expandType }}

Filter Code:

.filter('expandType', ['TypeService', function (tsvc) {
  return function (id) {
    return tsvc.types.get({ id: id });
  }
}])

The above code snippet uses the 'expandType' filter which references the TypeService service. The TypeService service makes use of the $resource method to retrieve data from the server with caching enabled:

.factory('TypeService', ['$resource', function ($resource) {
  var typeResource = $resource('/api/types/:id', { id: '@id' }, {
    get: { method: 'GET', cache: true, params: { id: '@id' } }
  });
  return {
    types: typeResource
  }
}])

Although I expected the cached resource to return the same object consistently to prevent any changes triggering additional digest cycles in AngularJS, I encountered an "infdig" error indicating an infinite loop during subsequent digests.

I verified that the caching mechanism is functional as there is only one request sent to the server when executing the get() method. Despite this, the issue persists.

How can I resolve this problem and successfully utilize the filter to expand IDs into complete objects?

Answer №1

It is not advisable to bind promises directly to the view, particularly in cases where filters are reevaluated with each digest cycle. According to https://docs.angularjs.org/api/ng/service/$http:

With cache enabled, $http stores server responses for future use. Subsequent requests for the same data can be served from cache without contacting the server again.

Note that even if a response is retrieved from cache, data delivery remains asynchronous as with regular requests.

It's worth noting that ngResource internally utilizes $http.

To utilize a filter within your controller:

app.filter('expandType', function ($http) {
  return function (id) {
    return $http.get('data.json');
  };
});

app.controller('MainCtrl', function ($scope, expandTypeFilter) {
  var typeId = 'hello';
  
  expandTypeFilter(typeId).success(function (data) {
    $scope.expandedTypeId = data[typeId];
  });
});

View Plunker example: http://plnkr.co/edit/BPS9IY?p=preview.

This method allows you to forego caching if the sole reason was to prevent redundant server calls. Fresh data retrieval can be ensured depending on your specific requirements.

Answer №2

I was determined to streamline my code by utilizing a filter that was widely used across the application, avoiding excessive clutter in my controllers. After much deliberation, I arrived at the following solution:

.filter('expandType', ['TypeService', function (tsvc) {
  var cache = {};
  return function (id) {
    if (!id) {
      return '';
    }
    var type = cache[id];
    if (!type) {
      tsvc.types.get({ id: id }).$promise.then(function (data) {
        cache[id] = data;
      });
      cache[id] = {}
      return cache[id];
    }
    else {
      return type;
    }
  }
}])

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

Smoothly transition with ease when hovering over a link

Hey there! I'm looking to create a menu that is similar to what you can find on this website: I've been thinking about using animate.css with the slideInDown animation to make the bookmark show up when hovering over a link. However, I'm not ...

Using Geolocation in HTML5 and JavaScript

Currently, I am working on my debut mobile web application and have successfully integrated Google Maps into it using Geolocation JavaScript API version 3. Now, I am looking to add a button that, when clicked by the user, centers the map on my location o ...

What is the best way to send an axios request in a Vue component to a route created by an Adonis controller?

My WidgetController.js file is responsible for handling CRUD operations on the database. Within this controller, there is a method/generator called * create (request, response) which returns widget attributes in a response and also inserts a new row into t ...

What could be causing my inability to accurately guess people's ages?

My latest project involves developing a game where players have to guess names from images. Each game consists of 10 rounds, followed by a bonus round where participants must wager their points on guessing the age of the person in the image within a 2-year ...

Obtain location data based on the adaptability of the design

As part of my plugin development, I want to track and save user mouse movements to create a heatmap representation. One challenge I'm facing is how to dynamically adjust the coordinates for different screen sizes as elements shift based on device widt ...

Having trouble locating the withArgs() method of the Spy class when using Jasmine and TypeScript

As per the Jasmine documentation, there is a method called withArgs() in the Spy object. spyOn(someObj, 'func').withArgs(1, 2, 3).and.returnValue(42); In the TypeScript-adapted version, I am unable to locate this method. My project was initiali ...

loading external files with processing.js

Splitting my processing.js code into multiple files is something I want to do, but I'm a bit unsure on how to proceed. I attempted using the following code: <script type="application/processing" src="main.pjs"> in order to load my processing.j ...

initiating a function on a separate webpage using ajax

Our website includes an IIFE script from a third party to check for a specific URL parameter and set a cookie. However, on another page, we need to set this parameter without redirecting the user, reloading the page, or altering the third-party code. The ...

Unable to access current props within useEffect block

When I use useEffect with the parameter props.quizStep, my function fn (which is a keydown event listener) is unable to access the current value of props.quizStep. I'm puzzled as to why it's not working properly. Can you help me understand? Bel ...

steps for populating default configurations in an angularjs application

As someone who is just starting out with AngularJS and MVC, I have a confession to make. In the past, my website development process was quite messy - some might call it "spaghetti code." Now, I'm looking to incorporate some basic settings into my w ...

How can one transform an array (in the form of a JSON array) into a map?

After running my script, I receive an array (JSON Array) structured like this: [{redirectCount=0, encodedBodySize=60962, unloadEventEnd=0, responseEnd=1601.699999999255, domainLookupEnd=995.7999999896856, ... Now, I want to display the key-value pairs fr ...

Enhance the sent server parameters by including extra options in fineuploader

I have successfully implemented file uploads using . Everything works perfectly. I am able to set parameters in the request object to send additional data to the server. However, when I try to add another parameter dynamically using the setParams function ...

The element possesses an implicit 'any' type as the expression containing 'string' cannot index the type '{}'

Question: I encountered the error "No index signature with a parameter of type 'string' was found on type '{}'. Below is the code snippet where the error occurred: const dnsListObj = {}; for (const key of dnsList) { dnsLis ...

Transforming JSON data in Node JS according to the city

I currently have a JSON object that contains information about various products and their details in different cities. const data = [ { "city name": "Chennai", "product name": "Apple", ...

Discovering a precise object from an array in MongoDB

Let's consider a scenario with the following MongoDB document: { "_id": { "$oid": "628f739398580cae9c21b44f" }, "place":"Amsterdam", "events": [ { "eventName": ...

What could be causing the lack of updates to my component in this todo list?

Based on my understanding, invoking an action in MobX should trigger a rerender for the observer. However, when I call the handleSubmit method in my AddTask component, it doesn't cause the TaskList observer to rerender. Should I also wrap AddTask in a ...

Running webpack to compile a TypeScript project

Here's a question for you - is there a way to achieve multi-file compilation while maintaining the folder and file structure, without explicitly specifying each file in the entry configuration like this? entry: { index:'./src/index.ts', ...

Nightwatch encounters difficulty in accessing the iframe element

While utilizing the xquery selector, I attempted to input a value into the iframe's input field, but unfortunately, my efforts were fruitless. `.frame('someid') .setValue('//input[contains(@name,"project name")]', 'Nig ...

Securing API endpoints in a React/Redux application using proxy techniques

Ensuring the security of my react/redux application is a top priority for me. I've noticed that my api url is exposed to the public inside the bundled app.js file, which raises some concerns. After doing some research, I discovered that some developer ...

Managing the creation of a fresh VueJs object with checkboxes enabled for CRUD operations

Hello fellow developers! I am currently working on a shop card project and I'm looking to add a new product to the collection of sale elements. Let's consider the JSON structure retrieved from the backend: "products": [ { "product_prov ...