Skip to content

Commit f8927ab

Browse files
committed
Add http interpolation demo.
1 parent 9f84191 commit f8927ab

File tree

4 files changed

+433
-0
lines changed

4 files changed

+433
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
<!doctype html>
2+
<html ng-app="Demo">
3+
<head>
4+
<meta charset="utf-8" />
5+
6+
<title>
7+
Using URL Interpolation With $http In AngularJS
8+
</title>
9+
10+
</head>
11+
<body ng-controller="DemoController">
12+
13+
<h1>
14+
Using URL Interpolation With $http In AngularJS
15+
</h1>
16+
17+
18+
<!-- Initialize scripts. -->
19+
<script type="text/javascript" src="../../vendor/jquery/jquery-2.1.0.min.js"></script>
20+
<script type="text/javascript" src="../../vendor/angularjs/angular-1.2.16.min.js"></script>
21+
<script type="text/javascript">
22+
23+
// Define the module for our AngularJS application.
24+
var app = angular.module( "Demo", [] );
25+
26+
27+
// -------------------------------------------------- //
28+
// -------------------------------------------------- //
29+
30+
31+
// I control the main demo.
32+
app.controller(
33+
"DemoController",
34+
function( $scope, httpi ) {
35+
36+
// NOTE: The (.|.) notation will be stripped out automatically; it's only
37+
// here to improve readability of the "happy paths" of labels. The
38+
// following urls are identical:
39+
// --
40+
// api/friends/( :listCommand | :id/:itemCommand )
41+
// api/friends/:listCommand:id/:itemCommand
42+
var url = "api/friends/( :listCommand | :id/:itemCommand )";
43+
44+
console.warn( "None of the API enpoints exist - they will all throw 404." );
45+
46+
// Clear list of friends - matching listCommand.
47+
httpi({
48+
method: "post",
49+
url: url,
50+
data: {
51+
listCommand: "reset"
52+
}
53+
});
54+
55+
// Create a new friend - no matching URL parameters.
56+
httpi({
57+
method: "post",
58+
url: url,
59+
data: {
60+
name: "Tricia"
61+
}
62+
});
63+
64+
// Get a given friend - ID matching.
65+
httpi({
66+
method: "get",
67+
url: url,
68+
data: {
69+
id: 4
70+
}
71+
});
72+
73+
// Make best friend - ID, itemCommand matching.
74+
httpi({
75+
method: "post",
76+
url: url,
77+
data: {
78+
id: 4,
79+
itemCommand: "make-best-friend"
80+
}
81+
});
82+
83+
// Get besties - no matching URL parameters.
84+
httpi({
85+
method: "get",
86+
url: url,
87+
params: {
88+
limit: "besties"
89+
}
90+
});
91+
92+
}
93+
);
94+
95+
96+
// -------------------------------------------------- //
97+
// -------------------------------------------------- //
98+
99+
100+
// I provide a proxy for the $http service that interpolates the URL of the
101+
// request before executing the underlying HTTP call.
102+
// --
103+
// NOTE: The "i" stands for "interpolation".
104+
app.service(
105+
"httpi",
106+
function( $http ) {
107+
108+
// Return the public API.
109+
return( httpProxy );
110+
111+
112+
// ---
113+
// PUBLIC METHODS.
114+
// ---
115+
116+
117+
// I proxy the $http service and merge the params and data values into
118+
// the URL before creating the underlying request.
119+
function httpProxy( config ) {
120+
121+
config.url = interpolateUrl( config.url, config.params, config.data );
122+
123+
return( $http( config ) );
124+
125+
}
126+
127+
128+
// ---
129+
// PRIVATE METHODS.
130+
// ---
131+
132+
133+
// I move values from the params and data arguments into the URL where
134+
// there is a match for labels. When the match occurs, the key-value
135+
// pairs are removed from the parent object and merged into the string
136+
// value of the URL.
137+
function interpolateUrl( url, params, data ) {
138+
139+
// Make sure we have an object to work with - makes the rest of the
140+
// logic easier.
141+
params = ( params || {} );
142+
data = ( data || {} );
143+
144+
// Strip out the delimiter fluff that is only there for readability
145+
// of the optional label paths.
146+
url = url.replace( /(\(\s*|\s*\)|\s*\|\s*)/g, "" );
147+
148+
// Replace each label in the URL (ex, :userID).
149+
url = url.replace(
150+
/:([a-z]\w*)/gi,
151+
function( $0, label ) {
152+
153+
// NOTE: Giving "data" precedence over "params".
154+
return( popFirstKey( data, params, label ) || "" );
155+
156+
}
157+
);
158+
159+
// Strip out any repeating slashes (but NOT the http:// version).
160+
url = url.replace( /(^|[^:])[\/]{2,}/g, "$1/" );
161+
162+
// Strip out any trailing slash.
163+
url = url.replace( /\/+$/i, "" );
164+
165+
return( url );
166+
167+
}
168+
169+
170+
// I take 1..N objects and a key and perform a popKey() action on the
171+
// first object that contains the given key. If other objects in the list
172+
// also have the key, they are ignored.
173+
function popFirstKey( object1, object2, objectN, key ) {
174+
175+
// Convert the arguments list into a true array so we can easily
176+
// pluck values from either end.
177+
var objects = Array.prototype.slice.call( arguments );
178+
179+
// The key will always be the last item in the argument collection.
180+
var key = objects.pop();
181+
182+
var object = null;
183+
184+
// Iterate over the arguments, looking for the first object that
185+
// contains a reference to the given key.
186+
while ( object = objects.shift() ) {
187+
188+
if ( object.hasOwnProperty( key ) ) {
189+
190+
return( popKey( object, key ) );
191+
192+
}
193+
194+
}
195+
196+
}
197+
198+
199+
// I delete the key from the given object and return the value.
200+
function popKey( object, key ) {
201+
202+
var value = object[ key ];
203+
204+
delete( object[ key ] );
205+
206+
return( value );
207+
208+
}
209+
210+
}
211+
);
212+
213+
</script>
214+
215+
</body>
216+
</html>

index.htm

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ <h1>
1313
</h1>
1414

1515
<ul>
16+
<li>
17+
<a href="./demos/http-interpolation-angularjs/">Using URL Interpolation With $http In AngularJS</a>
18+
</li>
1619
<li>
1720
<a href="./demos/find-shallow-comments-tree-walker/">Finding Shallow Comment Nodes In The DOM Using TreeWalker</a>
1821
</li>

0 commit comments

Comments
 (0)