Here's a straightforward issue with what I hope is an equally simple solution.
I've set up multiple services for handling CRUD operations with tags.
myApp.factory('GetTags', ['$resource', function ($resource) {
return $resource('/myApp/API/Service/GetTagList', {}, {
query: { method: 'GET', params: { groupId: 'groupId' }, }, isArray: true,
});
}]);
myApp.factory('GetTag', ['$resource', function ($resource) {
return $resource('/myApp/API/Service/GetTag', {}, {
query: { method: 'GET', params: { tagId: 'tagId' }, }, isArray: true,
});
}]);
myApp.factory('SaveTag', ['$resource', function ($resource) {
return $resource('/myApp/API/Service/CreateTag', {}, {
query: { method: 'POST', params: {/*createObj*/}, }, isArray: true,
});
}]);
myApp.factory('UpdateTag', ['$resource', function ($resource) {
return $resource('/myApp/API/Service/UpdateTag', {}, {
query: { method: 'POST', params: {/*updateObj*/}, }, isArray: true,
});
}]);
When I reach my controller, I want to achieve something like this within my tags function:
myApp.controller('myCtrl', ['$scope', '$routeParams', 'GetTags', 'GetTag', 'SaveTag', function ($scope, $routeParams, GetTags, GetTag, SaveTag) {
...
// The aim of this function is to maintain a local copy
// of the tags collection in memory that resembles the database
// while also adding selected tags to the forms object
// e.g. myForm = {... Tags: [], ...}
$scope.addtag = function (tag, subTag){
...
if (!($scope.tags.length > 0)) {
// Skip checking and simply add the tag
SaveTag.save({ Name: tag, Desc: "", ParentId: null, GroupId: 12, }, function (data) {
console.log('save tag: ', data);
//todo: should wait for data of save operation to comeback
// before moving on to requesting a full object
GetTag.get({ tagId: data.Id, groupId: 12, }, function (data) {
console.log(' get tag: ', data);
tagObj = data.tag;
});
});
// Push newly created tag into tags collection
$scope.tags.push(tagObj);
...
};
...
});
I omitted some detailed information from my controller and function in question but essentially, I use save
followed by get
due to the tag + subTag
scenario. I avoided complicating the logic by passing a complex object to the server. For instance, creating a tag
followed by a
subTag</code would look like this in JavaScript:</p>
<pre><code>...
// Skip checking and directly add tag and subTag
SaveTag.save({ Name: tag, Desc: "", ParentId: null, GroupId: 12, }, function (data) {
//todo: should wait for data of save operation to comeback
// before moving on to requesting a full object
GetTag.get({ tagId: data.Id, groupId: 12, }, function (data) {
tagObj = data.tag;
});
});
// Push newly created tag into tags collection
$scope.tags.push(tagObj);
SaveTag.save({ Name: subTag, Desc: "", ParentId: tagObj.ParentId, GroupId: 12, }, function (data) {
//todo: should wait for data of save operation to comeback
// before moving on to requesting a full object
GetTag.get({ tagId: data.Id, groupId: 12, }, function (data) {
tagObj = data.tag;
});
});
// Push newly created sub tag into tags collection
//todo: find parent index
$scope.tags[parent_index]["Elements"].push(tagObj);
...
If you're wondering, yes, returning the full object from the save
operation is something I might do soon. It's best to minimize the number of asynchronous calls for overall performance reasons.
However, I have a few queries at the moment:
- Currently, I have four separate services declared as per Angular documentation. It would be more efficient to consolidate them into a single factory with multiple functions. Can someone guide me in the right direction here please?
- Is there a way to pause and wait for the
data.$resolved
property to becometrue
after calling thesave
service so that I can then call theget
service with the returned value? Or is there an alternative approach? - I am exploring Angular Documentation's
$q
to see if I can utilize anything from there.
In case you're curious, I've encountered examples where people used the resolve
property with $routeProvider
, but my scenario involves real-time interactions during user actions.
Any assistance or advice is greatly appreciated.
References:
- AngularJS Docs - $q
- Informative explanation and examples - Using and chaining promises in AngularJS
- AngularJS Docs - $resource (last example demonstrates use of
$promise
)
Update:
It appears my instinct was correct. While I haven't figured it out yet, I believe the answer lies within utilizing $q
and chaining promises
. Now I just need to make it work.