Skip to content

Commit

Permalink
#23(feat): add fetchMultiple flag to resolve the same link multiple t…
Browse files Browse the repository at this point in the history
…imes
  • Loading branch information
guylabs committed Oct 28, 2016
1 parent 8b90c30 commit a35885b
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 23 deletions.
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -373,10 +373,21 @@ SpringDataRestAdapter.process(response, 'anotherLink', true).then(function(proce
});
```
Now the response of the `anotherLink` will be processed the same way as the main response was processed. But *be aware* when setting the recursive flag to true, because when your reponses of the links contain the same link name again, then it will end up in a infinite loop.
Now the response of the `anotherLink` will be processed the same way as the main response was processed. But *be aware* when setting the recursive flag to true, because when your responses of the links contain the same link name again, then it will end up in a infinite loop.
It will not fetch the `self` link as this would make no sense because the data is already in the response. The `self` key is also configurable. Read more [here](#configuration-of-the-springdatarestadapter).
As a last configuration option you are able to set the fourth parameter called `fetchMultiple` of the `process` method which is used to define if a link is fetched multiple times if the same link is contained in multiple links and you want to resolve each one of them. The drawback
is that it won't cache the responses in any way. So if you enable this then multiple network calls will be made. Here an example:
```javascript
SpringDataRestAdapter.process(response, 'anotherLink', true, true).then(function(processedResponse) {
...
});
```
:warning: If you set the `fetchMultiple` to `true` you could end up in an infinite loop if you have circular dependencies in your `_links`.
#### Fetch multiple or all links
If you want to fetch multiple links then you are able to add an array of strings with the given link names:
Expand Down Expand Up @@ -552,7 +563,7 @@ myApp.config(function (SpringDataRestAdapterProvider) {
SpringDataRestAdapterProvider.config({
fetchFunction: function (url, key, data, fetchLinkNames, recursive) {
var $http = angular.injector(['ng']).get('$http');

$http.get('/rest/endpoint').then(function (responseData) {
console.log(responseData);
})
Expand Down
24 changes: 14 additions & 10 deletions dist/angular-spring-data-rest.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,11 @@ angular.module("spring-data-rest").provider("SpringDataRestAdapter", function ()
* @param {object} data the data object reference in which the response is stored
* @param {[string]|string} fetchLinkNames the fetch link names to allow to process the fetched response
* @param {boolean} recursive true if the fetched response should be processed recursively with the
* @param {boolean} fetchMultiple true if multiple same link names should be resolved. ATTENTION: this could lead to
* an infinite loop when you have circular dependencies between the links.
* adapter, false otherwise
*/
function fetchFunction(url, key, data, fetchLinkNames, recursive) {
function fetchFunction(url, key, data, fetchLinkNames, recursive, fetchMultiple) {
if (config.fetchFunction == undefined) {
var promisesArray = [];

Expand All @@ -111,7 +113,7 @@ angular.module("spring-data-rest").provider("SpringDataRestAdapter", function ()

// wrap the response again with the adapter and return the promise
if (recursive) {
return processData(responseData.data, fetchLinkNames, true).then(function (processedData) {
return processData(responseData.data, fetchLinkNames, true, fetchMultiple).then(function (processedData) {
data[key] = processedData;
});
} else {
Expand All @@ -129,7 +131,7 @@ angular.module("spring-data-rest").provider("SpringDataRestAdapter", function ()
// wait for all promises to be resolved and return a new promise
return $injector.get("$q").all(promisesArray);
} else {
return config.fetchFunction(url, key, data, fetchLinkNames, recursive);
return config.fetchFunction(url, key, data, fetchLinkNames, recursive, fetchMultiple);
}
}

Expand All @@ -142,9 +144,11 @@ angular.module("spring-data-rest").provider("SpringDataRestAdapter", function ()
* 'fetchAllLinkNamesKey' key from the config object to fetch all links except the 'self' key.
* @param {boolean} recursive true if the automatically fetched response should be processed recursively with the
* adapter, false otherwise
* @param {boolean} fetchMultiple true if multiple same link names should be resolved. ATTENTION: this could lead to
* an infinite loop when you have circular dependencies between the links.
* @returns {object} the processed JSON data
*/
var processData = function processDataFunction(promiseOrData, fetchLinkNames, recursive) {
var processData = function processDataFunction(promiseOrData, fetchLinkNames, recursive, fetchMultiple) {

// convert the given promise or data to a $q promise
return $injector.get("$q").when(promiseOrData).then(function (data) {
Expand Down Expand Up @@ -274,12 +278,12 @@ angular.module("spring-data-rest").provider("SpringDataRestAdapter", function ()
// 2. the all link names key is given then fetch the link
// 3. the given key is equal
// 4. the given key is inside the array
if (linkMap[self].indexOf(linkName) < 0 &&
if ((fetchMultiple || linkMap[self].indexOf(linkName) < 0) &&
(fetchLinkNames == config.fetchAllKey ||
(typeof fetchLinkNames === "string" && linkName == fetchLinkNames) ||
(fetchLinkNames instanceof Array && fetchLinkNames.indexOf(linkName) >= 0))) {
promisesArray.push(fetchFunction(getProcessedUrl(data, linkName), linkName,
processedData, fetchLinkNames, recursive));
processedData, fetchLinkNames, recursive, fetchMultiple));
linkMap[self].push(linkName);
}
}
Expand Down Expand Up @@ -307,7 +311,7 @@ angular.module("spring-data-rest").provider("SpringDataRestAdapter", function ()
var processedDataArrayPromise;
angular.forEach(value, function (arrayValue, arrayKey) {
if (angular.isObject(arrayValue)) {
processedDataArrayPromise = processDataFunction({data: arrayValue}, fetchLinkNames, recursive).then(function (processedResponseData) {
processedDataArrayPromise = processDataFunction({data: arrayValue}, fetchLinkNames, recursive, fetchMultiple).then(function (processedResponseData) {
processedDataArray[arrayKey] = processedResponseData;
});
promisesArray.push(processedDataArrayPromise);
Expand All @@ -324,7 +328,7 @@ angular.module("spring-data-rest").provider("SpringDataRestAdapter", function ()
}
} else if (angular.isObject(value)) {
// single objects are processed directly
promisesArray.push(processDataFunction({data: value}, fetchLinkNames, recursive).then(function (processedResponseData) {
promisesArray.push(processDataFunction({data: value}, fetchLinkNames, recursive, fetchMultiple).then(function (processedResponseData) {
processedData[config.embeddedNewKey][key] = processedResponseData;
}));
}
Expand Down Expand Up @@ -378,9 +382,9 @@ angular.module("spring-data-rest").provider("SpringDataRestAdapter", function ()
// empty the map and
// return an object with the processData function
return {
process: function(promiseOrData, fetchLinkNames, recursive) {
process: function (promiseOrData, fetchLinkNames, recursive, fetchMultiple) {
linkMap = {};
return processData(promiseOrData, fetchLinkNames, recursive);
return processData(promiseOrData, fetchLinkNames, recursive, fetchMultiple);
}
};
}]
Expand Down
2 changes: 1 addition & 1 deletion dist/angular-spring-data-rest.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit a35885b

Please sign in to comment.