guylabs / angular-spring-data-rest Goto Github PK
View Code? Open in Web Editor NEWAn AngularJS module to ease the work with a Spring Data REST backend.
Home Page: http://guylabs.ch/project/angular-spring-data-rest
License: MIT License
An AngularJS module to ease the work with a Spring Data REST backend.
Home Page: http://guylabs.ch/project/angular-spring-data-rest
License: MIT License
My spring data rest implementation throws exception in some cases. I would like to handle that exception in the error part of the promise call. The issue is that the error part is not called.
var myHttpPromise = $http.post('http://localhost:54000/api/v1/systems', vm.data);
SpringDataRestAdapter.process(myHttpPromise)
.then(function (processedResponse) {
}, function(response) {
console.log(response);
});
I looked at the code in angular-spring-data-rest-interceptor-provider.js
and I was wondering if you should reject the promise in case of erros.
return SpringDataRestAdapter.process(response.data).then(function (processedResponse) {
response.data = processedResponse;
return response;
, function(response) {
return $q.reject(response);
});
SDR by default produces urls with templates similar to:
http://localhost:8080/api/users/0
Is it possible to get a $resource function with such template from a processed resource? So that api._resources('users') would return equivalent of $resource('/api/users/:userId'). Is this feature currently available?
Hi Guy,
I have another one :)
After automatic fetching data there is the usual "_embedded" attribute in it and not the "_embeddedItems" attribute.
I researched a little bit in the code and found out that the fetched data is actually not being processed. This is change, which fixes this issue.
Line 107:
if (recursive) {
return processData(responseData.data, fetchLinkNames, true).then(function (processedData) {
data[key] = processedData;
});
} else {
return processData(responseData.data).then(function (processedData) {
data[key] = processedData;
});
}
I have some HAL+JSON data which looks like:
{
"_embedded": {},
"_links": {
"self": {
"href": "http://localhost/api/article"
},
"api/article": [
{
"href": "/api/article/1"
},
{
"href": "/api/article/2"
},
{
"href": "/api/article/3"
},
{
"href": "/api/article/4"
}
]
}
}
Notice that the "api/article" key in "_links" has an array of objects. This is similar to the "admins" link on the HAL specification page: http://stateless.co/hal_specification.html
When I try to use the following bit of code:
SpringDataRestAdapter.process($http.get('/api/article'), 'api/article').then(function(processedResponse) {
console.log(processedResponse);
});
I get the following exception:
angular.js:13550` Error: The provided resource name 'api/article' has no valid URL in the 'href' property.
at checkUrl (angular-spring-data-rest.js:507)
at getProcessedUrl (angular-spring-data-rest.js:349)
at angular-spring-data-rest.js:281
at Object.forEach (angular.js:336)
at angular-spring-data-rest.js:267
at processQueue (angular.js:15961)
at angular.js:15977
at Scope.$eval (angular.js:17229)
at Scope.$digest (angular.js:17045)
at Scope.$apply (angular.js:17337)
Doing a quick bit of looking through the code... it looks like perhaps an array of links for the same key is not supported? Is this the case or am I doing something else wrong? I was expecting "processedResponse" to be an array of promises. How would you handle a collection of links?
Your projects seems promising but I have some difficulties with the documentation. You write:
Now you are able to instantiate the SpringDataRestAdapter object and process a given response:
var processedResponse = new SpringDataRestAdapter(response);
What is the 'response'? Do I have to get it "manually" with $http? What about ngResource that is used by angular-spring-data-rest itself?
Normally with ngResource you can create and use a resource service like this:
myApp.factory('Category', function ($resource) {
return $resource('category/:categoryId', {categoryId: '@id'});
}
$scope.categories = Category.query(); // in the controller
How can I use angular-spring-data-rest this way to also make use of all ngResource convenience functions like 'get' or 'save'?
Hi Guy, it's me again..
I'm working with the configuration 'embeddedNamedResources' to true. With this configuration when I receive a response like the following:
{
"_embedded": {
"externalUsers": []
},
"_links": {
"self": {
"href": "http://localhost:8080/Users/58130325-a4c7-483f-a37e-3ceee4ba50ba/externalUsers"
}
}
}
So there aren't any 'ExternalUser' object in the response. In this case, the call to the service responds with the error "Given data '' is not of type object.". This problem doesn't occur when working with the configuration 'embeddedNamedResources' setted to false (default).
Here is the angular code where the error occurs:
userService.get({'id': auth.getUserId()}).$promise.then(function(user){
user._resources('externalUsers').get().$promise.then(function (externalUsers) {
...
}).catch(function (error) {
console.log(error); //execution comes here and error contains the message
});
});
Thank you!
I'm experiencing problems when processing spring data rest responses like:
{
"_embedded" : {
"timeSeries" : [ {
"id" : 1400,
"lastDate" : "1991-01-06T23:00:00.000+0000",
"data" : [ 89.34576078, 90.86743282, 91.5561206, 91.52988487 ],
"tsDataType" : "CLOSE",
"_embedded" : {
"asset" : {
"id" : 15,
"ticker" : "BUHY:IND",
"description" : "Bloomberg USD High Yield Corporate Bond Index",
"provider" : "BLOOMBERG",
"assetClass" : "INDEX",
"indexType" : "BOND",
"assetClassForType" : "INDEX"
}
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/alphaquant-web/restdata/timeSeries/1400"
}
}
}, {
"id" : 52,
"lastDate" : "2015-05-31T22:00:00.000+0000",
"data" : [ 156.931961, 157.007523, 156.968109, 157.001785, 156.967865, 100.0 ],
"tsDataType" : "OPEN",
"_embedded" : {
"asset" : {
"id" : 15,
"ticker" : "BUHY:IND",
"description" : "Bloomberg USD High Yield Corporate Bond Index",
"provider" : "BLOOMBERG",
"assetClass" : "INDEX",
"indexType" : "BOND",
"assetClassForType" : "INDEX"
}
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/alphaquant-web/restdata/timeSeries/52"
}
}
} ]
}
}
I get this exception
"Given data '15' is not of type object."
when processing the response with SpringDataRestAdapter.process()
Hi..
I wanna ask..
Thank You
Hello.
I would like to try out this Angular plugin, but in my Spring Data Rest responses, all the _link contains the servlet context path. My application is under an HTTP server, so URL with a context path are all remapped to a wrong URL.
This is an example GET respnose on http://localhost/rest/measure
{
"_links" : {
"self" : {
"href" : "http://localhost/raspberry-grow-room/rest/measure{?page,size,sort}",
"templated" : true
}
},
"_embedded" : {
"measure" : [ {
"unit" : "°C",
"iconClass" : "fa fa-fire",
"_links" : {
"self" : {
"href" : "http://localhost/raspberry-grow-room/rest/measure/1"
},
"locales" : {
"href" : "http://localhost/raspberry-grow-room/rest/measure/1/locales"
}
}
} ]
},
"page" : {
"size" : 20,
"totalElements" : 1,
"totalPages" : 1,
"number" : 0
}
}
Can you see the problem? I want to remove the /raspberry-grow-room base path. Can you please help me?
Egidio
Would that be possible? Thanks.
Hi Guy,
great angular module! Do you consider to provide it through a CDN (jsdelvr or cdnjs or ...)?
Cheers,
Robert
Hi Guy,
I'm writing to you as a last resort to help solve my current issue. I have used your code earlier to fetch the underlying links data and it worked fine. Currently when I'm trying to use it, it is not working.
Not sure why.
Below is my code: I have included all the required dependencies and compared the code with your example. Everything seems fine.
JSON:
{ "amount": 0, "year": 2017, "month": 3, "assessmentDate": "2017-03-07T18:30:00.000+0000", "transactionBalance": null, "_links": { "self": { "href": "http://localhost:8080/totalcharges/1046" }, "currentCharges": { "href": "http://localhost:8080/totalcharges/1046" }, "homeId": { "href": "http://localhost:8080/totalcharges/1046/homeId" }, "communityInfo": { "href": "http://localhost:8080/totalcharges/1046/communityInfo" }, "hoaId": { "href": "http://localhost:8080/totalcharges/1046/hoaId" }, "assessmentRuleType": { "href": "http://localhost:8080/totalcharges/1046/assessmentRuleType" } } }
JS Code:
SpringDataRestAdapter.process($http.get('/totalcharges/search/findByHoaId_hoaId?hoaId=1289','homeId',true)).then(function (processedResponse) { console.log("Inside adapter all"); $scope.totalCharges = processedResponse._embeddedItems; console.log('attendance users '+ JSON.stringify($scope.totalCharges)); });
Can you help me with some troubleshooting steps?
Thanks,
Kiran
Hi Guy,
upfront: You can close this one if this is not the desired behavior.
If I call processData for automatic link fetching with link name that doesn't exist in the given data, there is no feedback, that the link name is wrong.
For example SpringDataRestAdapter.process(httpPromise, 'parent1', true) called in the example app just ignores that there is no parent1 link and returns the data unmodified.
I would expect this to result in an error like deferred.reject("The given link name: " + name + " can not be found") This would help to developers with messy API-Doc ;)
BR,
Shari
Your bower.json
requires AngularJS to be version ~1.3.15
which means any patch level greater than 1.3.15 but definitely a version less than 1.4. In my current project I would like to use the most recent AngularJS version 1.4.8 together with your module. The only way to make it work is to provide a custom resolution in my bower.json
which forces Bower to use version 1.4.8. This is a dirty workaround and produces warning during the build process.
I have already tested your module in conjunction with AngularJS 1.4.8 and it seems to work fine for my use cases. Therefore, could you please update your bower.json
to allow the recent version?
For example you could use the caret prefix instead: ^1.3.15
- This allows any minor version greater than 1.3.15 and less than 2.0, see https://github.com/npm/node-semver#caret-ranges-123-025-004
Hi Guy,
first of all I want to thank You for Your great work. I'm trying to use the fetch feature of the module and it didn't work for me at all. The resolvedResponse is always the same as before. I'm using v0.3.1
Than I tried the https://github.com/guylabs/angular-spring-data-rest-sample. The sample about automatic link fetching delivered a lot of 404s in the chromes console.
I have created a fork for the example with working parent structure and a pull request in the angular-spring-data-rest-sample repository so You can verify my problem.
I have also looked at the js-code and I'm almost sure that the problem is in the fetch function and the usage of the $http without resolving the promise.
Hope this can help You.
BR,
Shari
I would like to call several resources like that:
POST http://lolcahost:54000/api/v1/portfolios
PATCH http://lolcahost:54000/api/v1/portfolios/1
GET http://lolcahost:54000/api/v1/portfolios/1/evaluate
GET http://lolcahost:54000/api/v1/portfolios/1
GET http://lolcahost:54000/api/v1/portfolios/1/summaries
Process the output
I wrote that code but I am not sure it's the correct way to use SpringDataRestAdapter
. I also have an issue with one of the processed response that does not have a _resources object.
// POST http://lolcahost:54000/api/v1/portfolios
var myHttpPromise = $http.post('http://localhost:54000/api/v1/portfolios', {});
SpringDataRestAdapter.process(myHttpPromise)
.then(function (processedResponse) {
// PATCH http://lolcahost:54000/api/v1/portfolios/1
var self = processedResponse._links.self.href;
var data = {};
return SpringDataRestAdapter.process($http.patch(self, data));
})
.then(function (processedResponse) {
// GET http://lolcahost:54000/api/v1/portfolios/1/evaluate
var resources = processedResponse._resources("self/:id", {id: "evaluate"});
return SpringDataRestAdapter.process(resources.get());
})
.then(function (processedResponse) {
// GET http://lolcahost:54000/api/v1/portfolios/1
console.log(processedResponse);
// ERROR processedResponse does not have a _resources property
var resources = processedResponse._resources("self");
return SpringDataRestAdapter.process(resources.get());
.then(function (processedResponse) {
// GET http://lolcahost:54000/api/v1/portfolios/1/summaries
return processedResponse._resources('summaries');
})
.then(function (summaries) {
// Process the output
console.log(summaries);
}, function (response) {
console.log(response);
console.log(response.data.error);
logger.error(response.data.error);
});
Hey Guy,
Could I ask you a question if you have time? Sorry I realise this should have been an issue in it's own right.
I'm using SpringDataRestAdapter to interact with my spring data rest api. From the screen shot you can see that I've just loaded all the questions and I'm attempting to load their answers (one-to-many) relationship. In the debug window the _embeddedItems array is an array of Questions with _links to each questions answers. I'm trying to prompt SpringDataRestAdapter to autoload the answers by passing 'answers' as an argument to the processWithPromise call but to no avail.
The urls look like http://localhost:8080/api/questions http://localhost:8080/api/question/1/answers
The Question.loadAnswers(question) call is commented out... It works in that it loads the question's answers but I felt I was using the framework incorrectly.
Here is the method
Question.loadAnswers = function (question) {
question.answers = question.answers? question.answers : [];
angular.forEach(question._links.answers, function (answerLink) {
var deferred = $http.get(answerLink);
return SpringDataRestAdapter.processWithPromise(deferred).then(function (data) {
question.answers = data._embeddedItems;
});
});
};
Congratulations on an excellent piece of coding Guy! I've also posted this question up on stackoverflow in case the issue is with my understanding of promises as opposed to how to use the framework :)
http://stackoverflow.com/questions/36072090/springdatarestadapter-load-child-resources
Thanks, Mark.
Hi,
I have a collection of items, for which I have a projection setup in Spring boot, so that it inlines some data that I don't want to fetch for each item individually.
I'm doing the save with the following code:
this.clusterResponse._resources('self').save({ name: cluster.name, analysisMethods: cluster.analysisMethods.map((method) => method._links.self) }
,
but this returns me a resource with links, not taking into account the projection (since you need to add this explicitly by adding ?projection=name.
The only thing I want is to create a new cluster in this case, and add the item to the list, so I don't need to refresh the entire list or refetch the invidual item. Any examples on how to do this?
Is there a way to automatically retrieve links in a payload that looks like the below?
personprojectsesByPersonid: [ ],
personskillsesByPersonid: [
{
_links: {
skillsBySkillid: {
href: "http://localhost:8985/api/skills/1"
},
personByPersonid: {
href: "http://localhost:8985/api/people/4"
}
}
},
{
_links: {
skillsBySkillid: {
href: "http://localhost:8985/api/skills/2"
},
personByPersonid: {
href: "http://localhost:8985/api/people/4"
}
}
}
],
I've got a call that will return multiple entities. I've configured the SpringDataRestAdapter to recursively resolve multiple links.
This actually works fine, but my problem is the filter that ensures that each URL is called only once which leads to unpopulated fields if one of the entities has a link to an resource that was already fetched for another entity. This leaves all references after the first one empty.
While I do appreciate that each URL is only called once (I've already got 29 requests with only one call of SpringDataRestAdapter), it would be extremely useful if other entities that reference the same links would get populated aswell.
Hi,
I have a manyToOne relation between Type and Channel entities. When I prefetch the type and channels type.channel gets the embedded object inside. This is a problem when I try to save the resource because in order to work spring data rest is expecting type.channel to be an URL.
Is any possibility of saving resources work properly with prefetched children?
Thanks in advance.
Hi,
When we have a class "A" with two subclasses "B" and "C", we could have a spring data rest repository for the class "A" which would return all "B" and "C" objects in the following format:
{
"_embedded": {
"as": [ "A" class objects ],
"bs": [ "B" class objects ]
},
"_links": { ... },
"profile": { ... },
"search": { ... }
},
"page": { ... }
}
Would it be possible to know which is the class of each embedded object?
Thank you.``
Hi @guylabs
Can i add use cache: true
in $http ?
Hi @guylabs
Somehow API will return 204
rather than 404
for unknown links.
How can i handle this 204
code ? Now when i get 204
all of request will be break and nothing happened.
Thanks
Hi Guy,
could you please release version 0.4.6 with the latest fixes? That would be great!
Thanks in advance
Torsten
I have:
64: console.log(processedResponse);
65: console.log(processedResponse._embeddedItems);
66: console.log(processedResponse._resources());
The contents of processedResponse look correct, but _embeddedItems and _resources return squat.
Line 64 looks fine.
Line 65 is undefined.
Line 66 is undefined.
Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.