A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from http://www.bennadel.com/blog/2432-applying-a-cached-response-to-an-angularjs-resource.htm below:

Applying A Cached Response To An AngularJS Resource

Earlier this week, I demonstrated my AngularJS class, DeferredWithUpdate.js, as a way to apply cached responses to an AngularJS deferred value. As a follow up to that, I wanted to quickly demonstrate how to apply a cached response to an AngularJS $resource reference.

The AngularJS $resource module provides an abstraction for communicating with a remote API. Basically, you define what kind of actions can be performed on a remote resource and what kind of data is expected to be returned and AngularJS takes care of everything else.

This is nice; but, what's really cool is how AngularJS handles the return value. Unlike a Deferred / Promise value, the $resource module returns Array and Object references. At first, these objects are empty. But, when the server returns with data, AngularJS subsequently "hydrates" these empty objects with the deserialized data. This allows the $resource response to be injected into the Controller's $scope before the server has responded.

In this demo, I wanted to take a look at applying a cached response to these naked Array and Object $resource responses without messing up the object references. To do this, I've created a service object that encapsulates my $resource instance and injects cached values before returning the $resource:

<!doctype html>
<html ng-app="Demo">
<head>
	<meta charset="utf-8" />
	<title>Applying A Cached Response To An AngularJS Resource</title>
</head>
<body ng-controller="ListController">

	<h1>
		Applying A Cached Response To An AngularJS Resource
	</h1>

	<p>
		You have {{ friends.length }} friend(s).
	</p>

	<ul>
		<li ng-repeat="friend in friends">
			{{ friend.id }} : {{ friend.name }}
		</li>
	</ul>


	<!--Load AngularJS and the Resource module. -->
	<script type="text/javascript" src="./angular.min.js"></script>
	<script type="text/javascript" src="./angular-resource.min.js"></script>
	<script type="text/javascript">


		// Create an application module for our demo.
		var Demo = angular.module( "Demo", [ "ngResource" ] );


		// -------------------------------------------------- //
		// -------------------------------------------------- //


		// I control the demo UI.
		Demo.controller(
			"ListController",
			function( $scope, friendService ) {

				// Get the list of friends from the server. This
				// returns an AngularJS resource which can be injected
				// directly into the scope.
				$scope.friends = friendService.query();

			}
		);


		// -------------------------------------------------- //
		// -------------------------------------------------- //


		// I provide the access to the API.
		Demo.service(
			"friendService",
			function( $resource, applyCacheToResource ) {

				// Define our AngularJS resource (which makes the
				// HTTP requests to our server for us).
				var resource = $resource( "./api.cfm" );

				// Imagine that we have some locally cached data that
				// we've stored from a previous request.
				var cachedResponse = [
					{
						id: 3,
						name: "Joanna"
					}
				];


				// Provide an API for the controllers.
				this.query = function() {

					// Get the resource reference (at this point,
					// it is an empty array or object reference).
					var results = resource.query();

					// Before we return the resource, let's inject
					// our own cache. Since the Resource *always*
					// updates on the next "tick", we know that we
					// are not going to corrupt the true response
					// from the server.
					return(
						applyCacheToResource( results, cachedResponse )
					);

				};

			}
		);


		// -------------------------------------------------- //
		// -------------------------------------------------- //


		// I apply a cached response to an existing resource without
		// breaking the original resource reference.
		Demo.value(
			"applyCacheToResource",
			function( resource, cache ) {

				// Check to see what type of value we're dealing with.
				// If it's an array, we want to splice-in the cache;
				// if it's an object, we want to extend the keys.
				if ( angular.isArray( resource ) ) {

					resource.splice.apply(
						resource,
						[ 0, 0 ].concat( cache )
					);

				} else {

					angular.extend( resource, cache );

				}

				// Return the updated resource (for easy of use).
				return( resource );

			}
		);


	</script>

</body>
</html>

As you can see, I have an array of friends that is getting rendered in the main UI (user interface). The friend data is being retrieved from the server-side API using an AngularJS resource. My data access layer - friendService - applies a cached value to the response before returning it to the controller.

The cached value is being applied to the $resource with another helper method: applyCacheToResource(). In order to maintain the correct object references, the cached value is being used to "hydrate" - rather than replace - the $resource response. This allows (potentially dirty) data to be rendered early without messing up the normal $resource request lifecycle.

Want to use code from this post? Check out the license.

https://bennadel.com/2432


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4