angularjs return another promise in $q.all - angularjs

in my angularjs/ionic application I'm getting data from a sqlite database and want to get data from a web service which depends on the values of the database variables. I thought this might be possible with:
.factory('WebSrvs', function($http,DatabaseSrvs) {
var getData = function() {
var promiseReceiverUrl = DatabaseSrvs.getLocalValue('value1');
var promiseVehicleId = DatabaseSrvs.getLocalValue('value2');
$q.all([promiseReceiverUrl,promiseVehicleId]).then(function(results) {
if(results[0].rows.length > 0 && results[1].rows.length > 0) {
var v1 = results[0].rows.item(0).Value;
var v2 = results[1].rows.item(0).Value;
var req = {
method: 'POST',
url: v1,
headers: {
'Content-Type': 'application/json; charset=utf-8'
},
data: {
value: v2
},
timeout: 10000,
crossDomain: true
};
return $http(req);
}
});
}
}
But if do it this way and call it with var promise1 = WebSrvs.getData(); I don't get anything back and the app runs in a reloading queue which never ends. What am I doing wrong?

To add to my comments:
.factory('WebSrvs', function($http,DatabaseSrvs) {
var getData = function() {
var promiseReceiverUrl = DatabaseSrvs.getLocalValue('value1');
var promiseVehicleId = DatabaseSrvs.getLocalValue('value2');
return $q.all([promiseReceiverUrl,promiseVehicleId]).then(function(results) {
if(results[0].rows.length > 0 && results[1].rows.length > 0) {
var v1 = results[0].rows.item(0).Value;
var v2 = results[1].rows.item(0).Value;
var req = {
method: 'POST',
url: v1,
headers: {
'Content-Type': 'application/json; charset=utf-8'
},
data: {
value: v2
},
timeout: 10000,
crossDomain: true
};
return $http(req);
}
});
}
return {
getData: getData
};
}

In your factory implementation you need to first return getData function. Also inside getData function you have to return $q.all.
.factory('WebSrvs', function($http,DatabaseSrvs) {
var getData = function() {
var promiseReceiverUrl = DatabaseSrvs.getLocalValue('value1');
var promiseVehicleId = DatabaseSrvs.getLocalValue('value2');
return $q.all([promiseReceiverUrl,promiseVehicleId]).then(function(results) {
...
...
});
}
return {
getData: getData
}
}

Related

Two different controllers using same service and getting same result

I have created two common services for my all master modules. One using ng-resource.
app.service('CRUDService',function($resource, $window){
var data = JSON.parse($window.localStorage["userInfo"]);
this.crudFunction = function (url) {
return $resource(url , {id:'#_id'},{
update: {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept' : 'application/json',
'Authorization' : 'Bearer '+data['accessToken']
}
},
save: {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept' : 'application/json',
'Authorization' : 'Bearer '+data['accessToken']
}
},
remove: {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept' : 'application/json',
'Authorization' : 'Bearer '+data['accessToken']
}
},
get :{
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept' : 'application/json',
'Authorization' : 'Bearer '+data['accessToken']
}
}
});
}
});
And another service for common functions used by all controllers.
app.service('commonService', function (CRUDService) {
var vm = this;
var resourceUrl = apiUrl;
vm.totalItemsTemp = {};
vm.totalItems = 0;
vm.currentPage = 1;
vm.pageChanged = function(newPage) {
getResultsPage(newPage);
};
vm.load = function(url) {
resourceUrl = url;
getResultsPage(1);
}
function getResultsPage(pageNumber) {
CRUDService.crudFunction(resourceUrl).get({"page": pageNumber},function success(response) {
vm.listdata = response["data"];
vm.totalItems = response.total;
vm.currentPage = pageNumber;
},
function error(response) {
console.log(response);
});
}
vm.save = function() {
CRUDService.crudFunction(resourceUrl).save($.param(vm.newEntry),function(response) {
if(response["success"] == true)
{
vm.listdata.push(response["inserted_data"]);
getResultsPage(vm.currentPage);
$(".modal").modal('hide');
}
else
vm.msg = "Error Saving";
},function(response) {
vm.error = response['data'];
});
}
vm.create = function(){
vm.newEntry = {};
vm.editData = 0;
vm.error = {};
}
vm.edit = function(id,index) {
vm.newEntry = angular.copy(vm.listdata[index]);
vm.editData = 1;
vm.edit_index = index;
vm.error = {};
}
vm.update = function(id,index) {
vm.newEntry._method = "PUT";
CRUDService.crudFunction(resourceUrl).update({id : id} , $.param(vm.newEntry),function(response) {
if(response["success"] == true)
{
vm.listdata[index] = response["updated_data"];
$(".modal").modal('hide');
vm.newEntry = {};
}
else
vm.msg = "Error Updating";
},function(response) {
vm.error = response['data'];
});
}
vm.remove = function(id, index) {
var result = confirm("Are you sure you want to delete vm?");
if (result) {
CRUDService.crudFunction(resourceUrl).remove({id : id} , $.param({"_method" : "DELETE"}),function(response) {
getResultsPage(vm.currentPage);
},function(response) {
console.log(response);
});
}
}
});
And I am injecting commonService in my controller like this:
app.controller('UserRolesCtrl', function($scope, commonService) {
commonService.load(apiUrl + 'roles/:id');
$scope.userroles = commonService;
});
app.controller('SupportMembersCtrl', function($scope, commonService) {
commonService.load(apiUrl + 'supportmembers/:id');
$scope.supportmembers = commonService;
});
Now I am using tabs for each module. So that my all controllers will be in same page. But all the tabs showing same data. Is it because both controllers are using same variable names? But both the controller's references are different.
Is it because both controllers are using same variable names?
No. Each controller has his own scope so you can create variables with the same name
But both the controller's references are different.
The service is like singleton and you do 2 calls:
commonService.load(apiUrl + 'supportmembers/:id');
commonService.load(apiUrl + 'roles/:id');
The 1st problem is in method: run
you override resourceUrl twice
vm.load = function(url) {
resourceUrl = url; // <-- here
getResultsPage(1);
}
The 2nd problem - you store results under the same variables in service
vm.listdata = response["data"];
vm.totalItems = response.total;
vm.currentPage = pageNumber;
The one of solutions is to store data in map under unique key, in your case you can take your URL. Something like:
vm.load = function(url) {
//resourceUrl = url;
getResultsPage(1, url); // pass url as argument
}
function getResultsPage(pageNumber, url) {
CRUDService.crudFunction(url).get({"page": pageNumber},function success(response) {
// ...
},
function error(response) {
console.log(response);
});
}
Angularjs' services are singletons and you are injecting reference to the same service. Try to not assign results into
vm.listdata = response["data"];
vm.totalItems = response.total;
vm.currentPage = pageNumber;
But return it directly. Both methods saves results under the same properties od singleton. So only last result is available. I think so:)

Custom method in an Angular service using $resource in Jhipster

I don't understand the syntax to write a custom method in an Angular Service using $resource in Jhipster. After a lot of research, I am doubtful whether it's even possible.
Here is the code for Angular Service.
(function() {
'use strict';
angular
.module('tealboxApp')
.factory('Task', Task);
Task.$inject = ['$resource', 'DateUtils'];
function Task ($resource, DateUtils) {
var resourceUrl = 'api/tasks/:id';
return $resource(resourceUrl, {}, {
'query': { method: 'GET', isArray: true},
'get': {
method: 'GET',
transformResponse: function (data) {
if (data) {
data = angular.fromJson(data);
data.assignedDateTime = DateUtils.convertDateTimeFromServer(data.assignedDateTime);
data.startDateTime = DateUtils.convertDateTimeFromServer(data.startDateTime);
data.endDateTime = DateUtils.convertDateTimeFromServer(data.endDateTime);
data.startDate = DateUtils.convertLocalDateFromServer(data.startDate);
data.endDate = DateUtils.convertLocalDateFromServer(data.endDate);
}
return data;
}
},
'update': {
method: 'PUT',
transformRequest: function (data) {
var copy = angular.copy(data);
copy.startDate = DateUtils.convertLocalDateToServer(copy.startDate);
copy.endDate = DateUtils.convertLocalDateToServer(copy.endDate);
return angular.toJson(copy);
}
},
'save': {
method: 'POST',
transformRequest: function (data) {
var copy = angular.copy(data);
copy.startDate = DateUtils.convertLocalDateToServer(copy.startDate);
copy.endDate = DateUtils.convertLocalDateToServer(copy.endDate);
return angular.toJson(copy);
}
}
});
}
})();
I want to add a custom method like...
'getTasksWithXYZ': {
method: 'GET',
transformResponse: function (data) {
if (data) {
data = angular.fromJson(data);
data.assignedDateTime = DateUtils.convertDateTimeFromServer(data.assignedDateTime);
data.startDateTime = DateUtils.convertDateTimeFromServer(data.startDateTime);
data.endDateTime = DateUtils.convertDateTimeFromServer(data.endDateTime);
data.startDate = DateUtils.convertLocalDateFromServer(data.startDate);
data.endDate = DateUtils.convertLocalDateFromServer(data.endDate);
}
return data;
}
}
I am not sure how to pass a parameter to this get method or even how to call this method in the controller. How does one do this?
In your service add params
return $resource(resourceUrl, {}, {
'getTasksWithXYZ': {
method: 'GET',
params:{id:'#id'},
transformResponse: function (data) {
if (data) {
data = angular.fromJson(data);
data.assignedDateTime = DateUtils.convertDateTimeFromServer(data.assignedDateTime);
data.startDateTime = DateUtils.convertDateTimeFromServer(data.startDateTime);
data.endDateTime = DateUtils.convertDateTimeFromServer(data.endDateTime);
data.startDate = DateUtils.convertLocalDateFromServer(data.startDate);
data.endDate = DateUtils.convertLocalDateFromServer(data.endDate);
}
return data;
}
}
})
In your controller Task.getTasksWithXYZ(id)

GET call to REST API returns null

I am trying to make a GET call to test a REST API but it keeps returning null, is there anything I am doing wrong:
Making the call in controller.js
function ConsumerSearchCtrl($scope, BusinessCategoryService) {
console.log(BusinessCategoryService);
}
127.0.0.1:8000/api/category/ works perfectly fine
Code in services.js for API
/**
*
*/
function BusinessCategoryService(WenzeyAPI, $q) {
var scope = this;
scope.categories = categories;
function categories() {
var q = $q.defer();
WenzeyAPI.get('http://127.0.0.1:8000/api/category/').then(function success (res) {
q.resolve(res.data);
}, function failure (err) {
q.reject(err);
})
return q.promise;
}
}
/**
*
*/
function WenzeyAPI() {
var scope = this,
ip = "http://127.0.0.1:8000";
scope.get = get;
scope.post = post;
function get(url, data) {
data = data || {};
var req = {
method: 'GET',
url: url,
data: data
}
var q = $q.defer();
$http(req).then(function success(response) {
q.resolve(response);
}, function failure(err) {
q.reject(err);
});
return q.promise;
}
function post(url, data) {
data = data || {};
var req = {
method: 'POST',
url: url,
data: data
}
var q = $q.defer();
$http(req).then(function success(response) {
q.resolve(response);
}, function failure(err) {
q.reject(err);
});
return q.promise;
}
}
Removing WenzeyAPI and using $http resolved it.
function BusinessCategoryService($http) {
this.getAllData = function () {
return $http({
method: 'GET',
url: 'http://127.0.0.1:8000/api/category/',
});
}
}

AngularJS $resource Custom Action

I have just started using $resource to retrieve data and I'm having problems implementing a custom action. The standard GET is using an object ID as follows;
pageContentService.get({ pageId: 1 }, function (data) {
vm.pageContent = data.content;
});
I also want to be able to retrieve the same data using a string as follows;
pageContentService.getByPageName({ pageName: "Home" }, function (data) {
vm.pageContent = data.content;
});
My $resource service is;
(function () {
"use strict";
angular
.module("common.services")
.factory("pageContentService", ["$resource", pageContentService]);
function pageContentService($resource) {
return $resource("/api/pageContent/:pageId", null,
{
"getByPageName": { method: "GET", url: "/api/pageContent/:pageName", isArray: false }
});
};
})();
And I have mocked the backend as follows;
(function (undefined) {
"use strict";
var app = angular.module("pageContentServiceMock", ["ngMockE2E"]);
app.run(function ($httpBackend) {
var content = [
{ "pageId": 0, "pageName": "Unknown", "content": "<h1>Page not found</h1>" },
{ "pageId": 1, "pageName": "Home", "content": '<h1>Home Page</h1>' },
{ "pageId": 2, "pageName": "Programs", "content": '<h1>Programs Page</h1>' }
];
var contentUrl = "/api/pageContent";
$httpBackend.whenGET(contentUrl).respond(content);
var contentById = new RegExp(contentUrl + "/[0-9][0-9]*", '');
$httpBackend.whenGET(contentById).respond(function (method, url, data) {
var pageContent = content[0];
var parameters = url.split("/");
var length = parameters.length;
var pageId = parameters[length - 1];
if (pageId > 0) {
for (var i = 0; i < content.length; i++) {
if (content[i].pageId == pageId) {
pageContent = content[i];
break;
}
}
}
return [200, pageContent, {}];
});
var contentByName = new RegExp(contentUrl + "/[a-z][A-Z]*", '');
$httpBackend.whenGET(contentByName).respond(function (method, url, data) {
var pageContent = content[0];
var parameters = url.split("/");
var length = parameters.length;
var pageName = parameters[length - 1];
if (pageName.length > 0) {
for (var i = 0; i < content.length; i++) {
if (content[i].pageName == pageName) {
pageContent = content[i];
break;
}
}
}
return [200, pageContent, {}];
});
});
})();
The code works as expected when using the "pageId" to return the data however it doesn't appear to execute the "getByPageName" action of the service in the latter code.
From my understanding the custom action is used to extend the existing functionality of the standard $resource methods so I presume I am not implementing it correctly.
You can try with something like this:
angular.module('common.services').factory('pageContentService', ['$resource',
function($resource) {
return {
getByPageName: $resource('/api/pageContent/:pageName', {pageName: '#pageName'}, { method: "GET", isArray: false }),
getByPageId: $resource('/api/pageContent/:id', {id: '#id'}, { method: "GET", isArray: false })
};
}
]);
And after injecting pageContentService in a controller you can retrieve your data by:
pageContentService.getByPageName({ pageName: "Home" }, function (data) {
vm.pageContent = data.content;
});
Or:
pageContentService.getByPageId({ id: 1 }, function (data) {
vm.pageContent = data.content;
});
The problem turned out to be in the mocking. I was using;
var contentByName = new RegExp(contentUrl + "/[a-z][A-Z]*", '');
When I should have been using;
var contentByName = new RegExp(contentUrl + "/[a-zA-Z]+", '');
Once I fixed that I could use either;
pageContentService.get({ pageId: 1 }, function (data) {
vm.pageContent = data.content;
});
To retrieve the data using the default "GET" or;
pageContentService.getByPageName({ pageName: "Home" }, function (data) {
vm.pageContent = data.content;
});
To use the custom action. I also tried Michelem's suggestion using;
function pageContentService($resource) {
return {
"getByPageId": $resource('/api/pageContent/:pageId', null, { method: "GET", isArray: false }),
"getByPageName": $resource('/api/pageContent/:pageName', null, { method: "GET", isArray: false })
};
}
But I couldn't get this to work.

how to create a method in service for http post in angular?

i have
$http({
url: 'http://webapi.-----UA_WebApi/GetUserAccount',
method: 'POST',
params: {Username:Username, Password:Password},
headers: { 'Content-Type': 'application/json;charset=utf-8' },
})
and in my service i wrote this method :
PostLogin: function (apiName, params) {
var fullParams = getFullParams(apiName, params);
var promise = $resource(buildUrl(apiName), {}, POST).get(fullParams).$promise;
updateAllowedFilters(promise);
return promise;
}
if anyone could help me understand what i am doing (right and wrong) pls ?
i would also like an example in how to use the angular resource for post.
the PostLogin works
PostLogin: function (apiName, params) {
var fullParams = getFullParams(apiName, params);
var promise = $resource(buildUrl(apiName), {}, POST).get(fullParams).$promise;
updateAllowedFilters(promise);
return promise;
}
.then(function (results) {
if(results.data.TotalRows==1) {}
TotalRows is undefined when debugging. but there is TotalRows in the api
thanks
var actions = {
post: {
method: 'post',
transformResponse: function(data) {
// here is your chance to change received data
return new Model(angular.fromJson(data));
}
}
};
var url = "http://postSomeData/:id/somethingElse/:name";
var parameters = { id : 1, name : "test" }
var data = { name : "test", type : "some type" };
return $resource(url, parameters, actions).post(data).$promise;

Resources