Angular JS - Nested http calls to SharePoint Lists - javascript

We have a requirement on retrieving data from multiple SharePoint lists and creating a joined model to be displayed in the view. We have two lists Employee and Department. Employee list would have field as "Department" which needs to be joined with Department List's Title Field
Below is the controller along with used services, but it is not working as expected.
Employee List data
[
{
"Id": 1,
"Title": "1",
"Name": "ABC",
"Salary": 1000,
"Department": "1",
"ID": 1
},
{
"Id": 2,
"Title": "2",
"Name": "DEF",
"Salary": 600,
"Department": "2",
"ID": 2
},
{
"Id": 3,
"Title": "3",
"Name": "GHI",
"Salary": 500,
"Department": "3",
"ID": 3
}
]
Department List data
[
{
"Id": 1,
"Title": "1",
"Name": "DOC",
"Location": "DIJ",
"ID": 1
},
{
"Id": 2,
"Title": "2",
"Name": "DYU",
"Location": "RTY",
"ID": 2
},
{
"Id": 3,
"Title": "3",
"Name": "UCV",
"Location": "TYU",
"ID": 3
}
]
I am getting some [ngRepeat:dupes] error.
(function () {
angular.module("app")
.controller('homeCtrl', ['$scope', 'employeeService', 'departmentService', function ($scope, employeeService, departmentService) {
var employeevm = {};
var employeesvm = [];
employeeService.getAll()
.then(function (response) {
$scope.employees = response.d.results;
for (var i = 0; i < $scope.employees.length; i++) {
employeevm.Id = $scope.employees[i].Title;
employeevm.Name = $scope.employees[i].Name;
employeevm.Salary = $scope.employees[i].Salary;
departmentService.getItem($scope.employees[i].Department)
.then(function (response) {
$scope.department = response.d.results;
employeevm.DepartmentName = $scope.department[0].Name;
employeevm.Location = $scope.department[0].Location;
employeesvm.push(employeevm);
})
}
$scope.employeesvm = employeesvm;
})
}]);
})();
EmployeeService.js
"use strict";
(function () {
angular.module("app")
.factory("employeeService", ["baseSpServices", function (baseService) {
var listEndPoint = '/_api/web/lists';
var getAll = function () {
var query = listEndPoint + "/GetByTitle('Employee')/Items?$select=ID,Title,Name,Salary,Department";
return baseService.getRequest(query);
};
return {
getAll: getAll,
};
}]);
})();
departmentService.js
"use strict";
(function () {
angular.module("app")
.factory("departmentService", ["baseSpServices", function (baseService) {
var listEndPoint = '/_api/web/lists';
var getItem = function (id) {
var query = listEndPoint + "/GetByTitle('Department')/Items?$select=ID,Title,Name,Location&$filter=Title eq " + id;
return baseService.getRequest(query);
}
return {
getItem: getItem
};
}]);
})();
baseSPService.js
"use strict";
(function () {
angular.module("app")
.factory("baseSpServices", ["$http", "$q", "spContext", function ($http, $q, spContext) {
var baseUrl = _spPageContextInfo.siteAbsoluteUrl;
var getRequest = function (query) {
var deferred = $q.defer();
$http({
url: baseUrl + query,
method: "GET",
headers: {
"accept": "application/json;odata=verbose",
"content-Type": "application/json;odata=verbose"
}
})
.success(function (result) {
deferred.resolve(result);
})
.error(function (result, status) {
deferred.reject(status);
});
return deferred.promise;
};
var postRequest = function (data, url) {
var deferred = $q.defer();
$http({
url: baseUrl + url,
method: "POST",
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
"content-Type": "application/json;odata=verbose"
},
data: JSON.stringify(data)
})
.success(function (result) {
deferred.resolve(result);
})
.error(function (result, status) {
deferred.reject(status);
});
return deferred.promise;
};
var updateRequest = function (data, url) {
var deferred = $q.defer();
$http({
url: baseUrl + url,
method: "PATCH",
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
"content-Type": "application/json;odata=verbose",
"X-Http-Method": "PATCH",
"If-Match": "*"
},
data: JSON.stringify(data)
})
.success(function (result) {
deferred.resolve(result);
})
.error(function (result, status) {
deferred.reject(status);
});
return deferred.promise;
};
var deleteRequest = function (url) {
var deferred = $q.defer();
$http({
url: baseUrl + url,
method: "DELETE",
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": document.getElementById("__REQUESTDIGEST").value,
"IF-MATCH": "*"
}
})
.success(function (result) {
deferred.resolve(result);
})
.error(function (result, status) {
deferred.reject(status);
});
return deferred.promise;
};
return {
getRequest: getRequest,
postRequest: postRequest,
updateRequest: updateRequest,
deleteRequest: deleteRequest
};
}]);
})();

You haven't provided much information about what exactly is not working as expected.
Just by viewing your code it looks like your nested then could be the problem. You assign response.d.results to $scope.department, then read values from $scope.department and assign them to properties of employeevm. The problem is that the nested then runs multiple times, so the value assigned to $scope.department is going to change over time.
I'd suggest not assigning anything to $scope.department at all but instead just use the response directly, as follows:
.then(function (response) {
employeevm.DepartmentName = response.d.results[0].Name;
employeevm.Location = response.d.results[0].Location;
employeesvm.push(employeevm);
}
If that's not the problem please provide more information on what's not working.

I have modified my controller as below. I am pretty sure the issue was with handling the promises. Any help on handling error and other performance refinements is very much helpful
(function () {
angular.module("app")
.controller('homeCtrl', ['$filter', '$scope', '$q', 'employeeService', 'departmentService', function ($filter, $scope, $q, employeeService, departmentService) {
var departments = [];
var employeesvm = [];
employeeService.getAll()
.then(function (employees) {
var promises = [];
$scope.employees = employees.d.results;
angular.forEach($scope.employees, function (employee) {
promises.push(departmentService.getItem(employee.Department));
})
$q.all(promises).then(function (responses) {
departments = [];
angular.forEach(responses, function (response) {
departments.push(response.d.results[0]);
})
for (var i = 0; i < $scope.employees.length; i++) {
var employeevm = {};
employeevm.Id = $scope.employees[i].Title;
employeevm.Name = $scope.employees[i].Name;
employeevm.Salary = $scope.employees[i].Salary;
var department = $filter('filter')(departments, { Title: $scope.employees[i].Department });
employeevm.DepartmentName = department[0].Name;
employeevm.Location = department[0].Location;
employeesvm.push(employeevm);
}
$scope.employeesvm = employeesvm;
})
})
}]);
})();

Related

Angular throwing exception 'module cant be loaded'!

I was trying to clean my angular app code up. So I moved all the controllers in their own files. But when I moved the controllers, my main app stoped working and started throwing the exception below -
Error: $injector:modulerr
Module Error
Then I tried searching for the why the module won't load but with no luck.
main.js /*File where app module is declared*/
var app = angular.module('app', ['ngRoute','thatisuday.dropzone','UserController','LinkController','articleController']);
I tried injecting the dependency for the controller files.
Controllers:
Link Controller
var app = angular.module('app');
app.controller('LinkController', ['$scope','$http','$sce',function ($scope, $http, $sce) {
/*Sce declaration required for proxy settings*/
$scope.renderHtml = function (html_code) {
return $sce.trustAsHtml(html_code);
};
$scope.trustSrc = function (src) {
return $sce.trustAsResourceUrl(src);
};
/*First AJAX request which gets all the links and categories for the user*/
$http({
method: 'GET',
url: '/users'
}).then(function successCallback(response) {
$scope.user = response.data;
}, function errorCallback(response) {
});
$scope.getUser = function () {
$http({
method: 'GET',
url: '/users'
}).then(function successCallback(response) {
$scope.user = response.data;
}, function errorCallback(response) {
});
};
$http({
method: 'GET',
url: '/links'
}).then(function successCallback(response) {
this.orderProp = 'age';
/*the response is saved in scope variables*/
$scope.links = response.data[0];
$scope.categories = response.data[1];
$scope.categorytolink = response.data[2];
}, function errorCallback(response) {
console.log('There was a problem! Refresh!');
});
/*AJAX request for getting the recommendations according to the most viewed stars*/
$http({
method: 'GET',
url: '/recommendations/top'
}).then(function successCallback(response) {
$scope.recommendations = response.data;
}, function errorCallback(response) {
});
/*AJAX request when a user clicks a link retrieves the link data*/
$scope.getLinkData = function (link) {
$http({
method: 'GET',
url: "/proxy",
headers: {
"X-Proxy-To": link.rss_link
}
}).then(function successCallback(response) {
/*AJAX request: add a star to the link*/
$http.post('/links/' + link.id + '/views/add', {'link': link}).then(function successCallback(data, status, headers, config) {
// Manually increment star for link just clicked
var $data;
$data = data.data;
$scope.link = $data;
console.log('200 OK! Star added');
}, function errorCallback() {
console.log('Error!');
});
/*The data will be retrieved and will be sorted according to the requirements of welcome.blade*/
$myXml = response.data;
$xmlObj = $.parseXML($myXml);
$newsItems = [];
$channelImage = $($xmlObj).find("channel>image");
/*the information of the link is sorted */
$linkData = {
"title": $channelImage.find("title").text(),
"link": $channelImage.find("link").text(),
"imgurl": $channelImage.find("url").text()
};
/*the data is sorted below*/
$.each($($xmlObj).find("item"), function (index, value) {
$newsItems.push({
"title": $(value).find("title").text(),
"description": $(value).find("description").text(),
"link": $(value).find("link").text(),
"date_published": moment($(value).find("pubDate").text()).format('MMMM Do YYYY'),
"time_published": moment($(value).find("pubDate").text()).format('h:mm:ss a'),
"guid": $(value).find("guid").text()
})
});
$scope.newsItems = $newsItems;
$scope.linkData = $linkData;
}, function errorCallback(response) {
});
};
/*Create a category private to the user*/
$scope.create_category = function (category) {
/*AJAX request: adds a new category*/
$http.post('/categories/new', {'category': category}).then(function successCallback(response) {
/*AJAX request: Updates the categories for the use of new category*/
$http({
method: 'GET',
url: '/categories'
}).then(function successCallback(response) {
$scope.categories = response.data;
}, function errorCallback(response) {
});
}, function errorCallback(response) {
});
};
}]);
User Controller
var app = angular.module('app');
app.controller("UserController", ['$scope','$http','$sce', function ($scope, $http, $sce) {
/*Sce declaration required for proxy settings*/
$scope.renderHtml = function (html_code) {
return $sce.trustAsHtml(html_code);
};
$scope.trustSrc = function (src) {
return $sce.trustAsResourceUrl(src);
};
$scope.dzOptions = {
paramName: "file",
dictDefaultMessage: "<h4><i class='fa fa-camera'></i> <b>Upload</b></h4>",
createImageThumbnails: false,
autoDiscover: false
};
$scope.dzCallbacks = {
'sending': function (file, xhr, formData) {
formData.append('_token', $('#csrf-token').val());
},
'success': function (file, response) {
$scope.user = response;
$.notify("Profile photo changed!", "success", {autoHide: true, autoHideDelay: 500});
}
};
/*Update user info*/
$scope.updateUser = function () {
/*AJAX request: update user info*/
$http.post('/users/update', {
'name': $scope.user.name,
'username': $scope.user.username,
'email': $scope.user.email
}).then(
function successCallback(data) {
$scope.user = data;
$.notify("User updated!", "success", {autoHide: true, autoHideDelay: 500});
console.log('200 OK! User updated');
}, function errorCallback() {
console.log('Error!');
});
};
}]);
Article Controller
var app = angular.module('app');
app.controller("articleController", ['$scope','$http','$sce', function ($scope, $http, $sce) {
/*Sce declaration required for proxy settings*/
$scope.renderHtml = function (html_code) {
return $sce.trustAsHtml(html_code);
};
$scope.trustSrc = function (src) {
return $sce.trustAsResourceUrl(src);
};
/*Populates the comments for particular
* */
$scope.populatecomments = function (newsItem) {
$http({
method: 'GET',
url: '/articles/' + newsItem.guid + '/comments'
}).then(function successCallback(response) {
$scope.comments = response.data;
}, function errorCallback(response) {
});
};
$scope.data = [];
$scope.comment = [];
$scope.btn_add = function (newsItem) {
if ($scope.txtcomment != '') {
$scope.data.push({
"comment": $scope.txtcomment,
"guid": newsItem.guid
});
$http.post('/comments/new', {
"comment": $scope.txtcomment,
"guid": newsItem.guid
}).then(function successCallback() {
var encodedURI = encodeURIComponent(newsItem.guid);
$http({
method: 'GET',
url: '/articles/' + encodedURI + '/comments'
}).then(function successCallback(response) {
$scope.comments = response.data;
$scope.txtcomment = "";
}, function errorCallback(response) {
});
}, function errorCallback() {
console.log('Error comment!');
});
}
};
$scope.savearticle = function (newsItem) {
$http.post('/saved-articles/save', newsItem).then(function successCallback(response) {
/*console.log(document.getElementById("save/"+newsItem.guid).className="disabled");*/
}, function errorCallback(response) {
});
}
/**
* The saved articles by the user will be retrieved when a button clicked
*/
$scope.getSavedArticles = function () {
/*AJAX request: retreive the saved the saved articles for the user*/
$http({
method: 'GET',
url: '/saved-articles'
}).then(function successCallback(response) {
$scope.linkData = null;
$scope.newsItems = response.data;
}, function errorCallback(response) {
});
};
}]);
HELP needed!
Yo do not need to declare module in each controller file. Remove the line in each controller
var app = angular.module('app');
You are injecting controller in you module like dependency.
Change your main.js file to this:
var app = angular.module('app', ['ngRoute','thatisuday.dropzone']);
#Sajeetharan is right you do not need module declaration in all controllers.
Since you are using laravel according to your comment. ( It will conflict with your blade template because both use same {{ }} for variables )
There are two ways to do this:
Change the Angular Tags
var app = angular.module('app', [], function($interpolateProvider) {
$interpolateProvider.startSymbol('<%');
$interpolateProvider.endSymbol('%>');
});
Now Laravel will use the {{ variableName }} and Angular will use <%
variableName %>.
Change the Laravel Blade Tags
Blade::setContentTags('<%', '%>');// for variables and all things Blade
Blade::setEscapedContentTags('<%%', '%%>');// for escaped data
Variables will be: <% $variable %>. Comments will be: <%-- $variable
--%>. Escaped data will look like: <%% $variable %%>.
You can check this Tutorial for more info.

How to call nest factory in Angularjs?

Hi I am developing web application in angularjs. I have requirement below. I have one factory. I have added code snippet below.
myapp.factory('sadadpaymentapi', ['$http', '$cookieStore', 'cfg', 'ScrollFunction', 'leaselisting', function ($http, $cookieStore, cfg, ScrollFunction, leaselisting) {
var sadadpaymentapiobject = {};
var baseurl = cfg.Baseurl;
var LoginID = $cookieStore.get("LoginID");
var cookiePreferredLanguage = $cookieStore.get('PreferredLanguage');
var urlapi = baseurl + "api/ServiceRequest/CreateRSSedad/";
sadadpaymentapiobject.callsadad = function (PaymentType) {
leaselisting.leaselisting().then(function (response) {
//Problem in calling
}, function (error) { });
var request = {
url: urlapi,
method: 'POST',
data: {
SRActivityID: LoginID,
PaymentType: PaymentType,
PaymentAmount: "100"
},
headers: ScrollFunction.getheaders()
};
return $http(request);
}
return sadadpaymentapiobject;
}]);
Here is my second factory leaselisting
myapp.factory('leaselisting', ['$http', '$cookieStore', 'cfg', 'ScrollFunction', function ($http, $cookieStore, cfg, ScrollFunction) {
var leaselistingobject = {};
var baseurl = cfg.Baseurl;
var LoginID = $cookieStore.get("LoginID");
var cookiePreferredLanguage = $cookieStore.get('PreferredLanguage');
leaselistingobject.leaselisting=function(){
var requestObj = {
url: "api/ServiceRequest/GetROLSPSRLeaseList/",
data: {
LoginID: LoginID,
RSAccountNumber: $cookieStore.get("AccountNumber")
},
headers: ScrollFunction.getheaders()
};
$http(requestObj).then(function (response) {
}, function (error) {
});
}
return leaselistingobject;
}]);
I have found error in below line
leaselisting.leaselisting().then(function (response) { //Problem in calling
}, function (error) { });
May i am i doing anything wrong in the above code? May i know is it possible to call one factory from another? The response i get from leaselisting i want to pass it in callsadad function of sadadpaymentapi. So can someone hep me in the above code? I am getting error Cannot read property 'then' of undefined in the leaselisting.leaselisting().then(function (response) {},function(error){});
Also is there any way I can directly inject factory like payment amount: inject factory something like this?
I assume, that leaselistingobject.getValue is an asynchronous function.
So first of get your value :
leaselistingobject.getValue = function(){
var requestObj = {
url: "api/ServiceRequest/getValue/"
};
return $http(requestObj).then(function (response) {
return response.data;
});
}
And then use it. To let all async actions finish we use angulars $q.Here you can find a small tutorial.
myapp.factory('sadadpaymentapi', ['$http', '$cookieStore', 'cfg', 'ScrollFunction', 'leaselisting', '$q',function ($http, $cookieStore, cfg, ScrollFunction, leaselisting, $q) {
var sadadpaymentapiobject = {};
var baseurl = cfg.Baseurl;
var LoginID = $cookieStore.get("LoginID");
var cookiePreferredLanguage = $cookieStore.get('PreferredLanguage');
var urlapi = baseurl + "api/ServiceRequest/CreateRSSedad/";
sadadpaymentapiobject.callsadad = function (PaymentType) {
var leastListingPromise = leaselisting.leaselisting();
var getValuePromise = leaselisting.getValue();
$q.all([leastListingPromise, getValuePromise]).then(function (responses) {
//Here you have both responses in an array
var request = {
url: urlapi,
method: 'POST',
data: {
SRActivityID: LoginID,
PaymentType: PaymentType,
PaymentAmount: responses[1]
},
headers: ScrollFunction.getheaders()
};
return $http(request);
});
}
return sadadpaymentapiobject;
}]);
To make leaselisting() return the response of the request change the end of the function from
$http(requestObj).then(function (response) {
}, function (error) {
});
to
return $http(requestObj).then(function (response) {
return response.data;
}, function (error) {
});
If wont do anything about possible errors you can omit the error function part:
return $http(requestObj).then(function (response) {
return response.data;
});

My AngularJS model only updates when my button is clicked twice

I have a select list box, and the I have a button. Based on the button selectId, I have to filter the model which showing in the select list box.
The problem here is that the model only updates when I click this button twice. I have a filter function in GetFormsClicked which have logic regarding this.
My Angular controller is the following:
(function() {
var controllerId = 'GroupsController';
ig.app.controller(controllerId, ['$scope', '$log', '$http', '$compile', 'fileRvwQuestSvc', 'DataSvc',
function($scope, $log, $http, $compile, fileRvwQuestSvc, DataSvc) {
$scope.FrequencyMap = {
1: "Annual",
2: "Monthly",
3: "Half Year"
};
$scope.FormMap = {
1: "CMSMISC",
2: "CMSFPEA",
3: "CMSPIID",
5: "CMSMSR",
7: "CMSCOI"
}
$scope.GetAllGroupForms = function(Id) {
var url = '/GroupForm/Details/' + Id;
$scope.loading = true;
DataSvc.getAjaxData(url)
.then(function(data) {
//success
$scope.GroupForm = data.data;
$scope.GroupFormBack = data.data;
$scope.loading = false;
}, function(httpStatus) {
//failed
$scope.hasErrors = true;
if (httpStatus === 404) {
$scope.errorMessage = "Couldn't retrieve Users Info";
} else {
$scope.errorMessage = 'The system could not process your request, please try again or contact the system administrator.';
}
$log.warn(httpStatus);
$scope.loading = false;
});
};
$scope.availableFormsTestOriginal = [
{
"Id": null,
"GroupId": null,
"FormId": 1,
"SortOrder": null,
"Frequency": 1,
"IsCollapsed": false,
"IsDeleted": false
},
{
"Id": null,
"GroupId": null,
"FormId": 2,
"SortOrder": null,
"Frequency": 1,
"IsCollapsed": false,
"IsDeleted": false
},
{
"Id": null,
"GroupId": null,
"FormId": 3,
"SortOrder": null,
"Frequency": 1,
"IsCollapsed": false,
"IsDeleted": false
}
]
var AddGroupForm = function() {
$scope.loading = true;
var url = '/GroupForm/Create/';
DataSvc.AddFormData(url, $scope.GroupForm)
.then(function(data) {
//success
$scope.loading = false;
//$scope.successMessage = "Form Saved Successfully";
$scope.successMessage = "GroupForm Updated Successfully";
}, function(httpStatus) {
//failed
$scope.hasErrors = true;
if (httpStatus === 404) {
$scope.errorMessage = "Couldn't retrieve Users Info";
} else {
$scope.errorMessage = 'The system could not process your request, please try again or contact the system administrator.';
}
$log.warn(httpStatus);
$scope.loading = false;
});
}
$scope.filterailableforms = function() {
for (i = 0; i < $scope.availableFormsTest.length; i++) {
for (j = 0; j < $scope.GroupForm.length; j++) {
if ($scope.availableFormsTest[i].FormId === $scope.GroupForm[j].FormId && $scope.availableFormsTest[i].Frequency === $scope.GroupForm[j].Frequency) {
$scope.availableFormsTest.splice(i, 1);
}
}
}
}
activate();
$scope.GetFormsClicked = function(selectid) {
$scope.availableFormsTest = angular.copy($scope.availableFormsTestOriginal);
$scope.GetAllGroupForms(selectid);
$scope.updateavailableforms(selectid);
$scope.filterailableforms();
}
function activate() {
$scope.loading = false;
$scope.GetAllGroup();
}
}
]);
})();
My view code is as follows:
<button ng-click="GetFormsClicked(selectedId)">Select Group <span style="color:black"></span></button>` <select size="5" multiple ng-model="available" ng-options="x as FormMap[x.FormId]+' --- '+FrequencyMap[x.Frequency] for x in availableFormsTest" style="width: 400px"></select>
My dataser code:
ig.app.factory('DataSvc', [
'$http', '$q', '$log',
function ($http, $q, $log) {
return {
getAjaxData: function (CtrlUrl) {
var deferred = $q.defer();
var rnd = ((Math.random() * 1000000) + 1);
$http({
method: 'GET',
url: CtrlUrl + "/?r=" + rnd
})
.then(function (data, status, headers, config) {
deferred.resolve(data, status, headers, config);
},
function (data, status, headers, config) {
$log.warn(data, status, headers(), config);
deferred.reject(status);
});
return deferred.promise;
},
AddFormData: function (CtrlUrl, model) {
var deferred = $q.defer();
$http.post(CtrlUrl, model).then(function (data, status, headers, config) {
deferred.resolve(data, status, headers, config);
},function (data, status, headers, config) {
$log.warn(data, status, headers(), config);
deferred.reject(status);
});
return deferred.promise;
},
UpdateFormData: function (CtrlUrl, model) {
var deferred = $q.defer();
$http.post(CtrlUrl, model).then(function (data, status, headers, config) {
deferred.resolve(data, status, headers, config);
},function (data, status, headers, config) {
$log.warn(data, status, headers(), config);
deferred.reject(status);
});
return deferred.promise;
}
}
}]);
Your problem is due to the use of ng-model="variable".
The rule is "always have a dot in your ng-model", you should have a ng-model="obj.variable" with the correct obj.
The reason is that each directive with scope:true inherits the parent scope, and the "variable" you are editing isn't copied back to the parent.
The problem is due to the fact that the strings are copied by value.
By using an object, all the scope will reference the same variable.

How to return transformed data from a $http.json request in angular?

How can I return the APIData.map and not the default success APIdata using $http.jsonp?
LangDataService Constructor:
languages.LangDataService = function($http, $q) {
this.langDefer = $q.defer();
this.isDataReady = this.langDefer.promise;
};
languages.LangDataService.prototype.getApi = function() {
return this.isDataReady = this.http_.jsonp(URL, {
params: {}
})
.success(function(APIData) {
return APIData.map(function(item){
return item + 1; //just an example.
});
});
};
A Ctrl using LandDataService:
languages.LanguageCtrl = function(langDataService) {
languages.langDataService.isDataReady.then(function(data){
console.log('whooo im a transformed dataset', data);
});
}
Use then instead of success in getApi function.
Try a version of the following:
https://jsfiddle.net/L2ndft4w/
// define the module for our AngularJS application
var app = angular.module('App', []);
app.factory('LangDataService', function($q,$http) {
return {
getApi: function() {
var defer= $q.defer();
$http({
url: 'https://mysafeinfo.com/api/data?list=zodiac&format=json&alias=nm=name',
dataType: 'json',
method: 'GET',
data: '',
headers: {
"Content-Type": "application/json"
}
}).
success(function (data) {
defer.resolve(data.map(function(item){
return item.name;
}));
})
return defer.promise;
}
};
});
// invoke controller and retrieve data from $http service
app.controller('DataController', function ($scope, LangDataService) {
LangDataService.getApi().then(function(data){
$scope.data = JSON.stringify(data, null, 2);
});
});
Returns:
[
"Aquarius",
"Aries",
"Cancer",
"Capricorn",
"Gemini",
"Leo",
"Libra",
"Ophiuchus",
"Pisces",
"Sagittarius",
"Scorpio",
"Taurus",
"Virgo"
]
Although, since $http is already a promise, there's probably a shorter way to do this... ($q.when?)

Why is my factory getting an injector error?

I can't seem to figure out why I can't load my AuthFactory factory in my controller. The syntax looks correct to me. Also note, the portalAPI factory is built out the same way as the AuthFactory, howver it is being injected correctly. If someone could help me out I would greatly appreciate it:
(function() {
var app = angular.module('contactAuthApp');
//////////////////////////
// BEGIN - CONTROLLER
//////////////////////////
var ContactAuthController = function($rootScope, $scope, $stateParams, $state, $timeout, portalAPI, $location, AuthFactory) {
$scope.resetcode = $location.hash();
$scope.loggedIn = false;
$scope.errormsgheader;
$scope.errormsgbody;
$scope.successmsgheader;
$scope.successmsgbody;
$scope.errDialogHidden = true;
$scope.successDialogHidden = true;
var onUserComplete = function(response) {
for (var i in response.contact) {
var obj = response.contact[i];
$rootScope.user = obj;
}
$rootScope.companies = response.companies;
//$rootScope.databases = response.databases;
for (var i in response.databases) {
var obj = response.databases[i];
//$scope.secondaryData.push(obj);
$rootScope.databaseName = obj.databasename;
}
for (var i in $rootScope.companies) {
var obj = $rootScope.companies[i];
//$scope.secondaryData.push(obj);
$rootScope.companyID = obj.ID;
$rootScope.companyOptions = [{
name: obj.name,
id: obj.ID
}];
}
$scope.loggedIn = true;
portalAPI.getCompanyBrands($rootScope.companyID, 'active').success(goTest).error(goCharts);
};
var onForgotPasswordComplete = function(response) {
/* Show/hide windows and alerts */
$scope.errDialogHidden = true;
$scope.successDialogHidden = false;
$scope.successmsgheader = response.success.heading;
$scope.successmsgbody = response.success.body;
$timeout(function() {
$state.go('/');
}, 4000);
};
var goWelcome = function(response) {
$state.go('welcome');
//$state.go("welcome");
var data = response.companybrands;
$rootScope.brandOptions = [];
for (var i in data) {
var obj = {
name: data[i].Name,
id: data[i].ID
};
$rootScope.brandOptions.push(obj);
}
};
var goTest = function() {
var g = AuthFactory.isAuthenticated();
//$state.go("testing");
}
var goCharts = function() {
$state.go("chart");
}
var goDashboard = function() {
$state.go('dashboard');
}
var onError = function(response) {
var error = response.error;
$scope.errDialogHidden = false;
$scope.errormsgheader = error.heading;
$scope.errormsgbody = error.body;
$scope.successDialogHidden = true;
};
$scope.authenticate = function() {
portalAPI.getUser($scope.username, $scope.password).success(onUserComplete).error(onError);
};
$scope.newPassRequest = function() {
portalAPI.getForgotPassword($scope.username).success(onForgotPasswordComplete).error(onError);
};
$scope.newPassRequestVerify = function() {
portalAPI.getForgotPasswordVerify($scope.username, $scope.resetcode, $scope.newpassword, $scope.confirmnewpassword).success(onForgotPasswordComplete).error(onError);
};
$scope.submitparameters = function() {
$rootScope.startDate = $scope.startDate;
$rootScope.endDate = $scope.endDate;
$rootScope.clientdb = $rootScope.databaseName;
$rootScope.companyid = $scope.companyOptions.id.id;
$rootScope.brandid = $scope.brandOptions.id.id;
// The number of milliseconds in one day
var ONE_DAY = (1000 * 60 * 60 * 24);
// Convert both dates to milliseconds
var date1_ms = Date.parse($rootScope.startDate)
var date2_ms = Date.parse($rootScope.endDate)
// Calculate the difference in milliseconds
var difference_ms = Math.abs(date1_ms - date2_ms)
// Convert back to days and return
$rootScope.diffDays = Math.round(difference_ms / ONE_DAY)
$state.go('dashboard');
}
};
//////////////////////////
// END - CONTROLLER
//////////////////////////
/////////////////////////
// BEGIN - FACTORIES
/////////////////////////
var portalAPI = function($http) {
var getUser = function(username, password) {
return $http({
url: "https://staging.revguard.net/portalapi/index.php",
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
method: 'POST',
responseType: 'json',
data: {
"authentication": [{
"apiusername": "jaime",
"apipassword": "summit",
"apicompanyid": 3
}],
"controller": "Contact",
"method": "contactAuthenticate",
"params": [{
"username": username,
"password": password
}]
}
})
.success(function(response) {
//console.log("success"); console.log(response)
return response;
})
.error(function(response) {
//console.log("error"); console.log(response);
return response;
});
};
var getCompanyBrands = function(companyid, status) {
return $http({
url: "https://staging.revguard.net/portalapi/index.php",
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
method: 'POST',
responseType: 'json',
data: {
"authentication": [{
"apiusername": "jaime",
"apipassword": "summit",
"apicompanyid": 3
}],
"controller": "CompanyBrand",
"method": "getCompanyBrands",
"params": [{
"companyid": companyid,
"status": status
}]
}
})
.success(function(response) {
return response;
})
.error(function(response) {
return response;
});
};
var getForgotPassword = function(username) {
return $http({
url: "https://staging.revguard.net/portalapi/index.php",
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
method: 'POST',
responseType: 'json',
data: {
"authentication": [{
"apiusername": "jaime",
"apipassword": "summit",
"apicompanyid": 3
}],
"controller": "Password",
"method": "forgotPasswordTrigger",
"params": [{
"username": username
}]
}
})
.success(function(response) {
return response;
})
.error(function(response) {
return response;
});
};
var getForgotPasswordVerify = function(username, resetcode, newpassword, verifynewpassword) {
return $http({
url: "https://staging.revguard.net/portalapi/index.php",
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
method: 'POST',
responseType: 'json',
data: {
"authentication": [{
"apiusername": "jaime",
"apipassword": "summit",
"apicompanyid": 3
}],
"controller": "Password",
"method": "forgotPasswordVerify",
"params": [{
"username": username,
"resetcode": resetcode,
"newpassword": newpassword,
"verifypassword": verifynewpassword
}]
}
})
.success(function(response) {
return response;
})
.error(function(response) {
return response;
});
};
return {
getUser: getUser,
getCompanyBrands: getCompanyBrands,
getForgotPassword: getForgotPassword,
getForgotPasswordVerify: getForgotPasswordVerify
};
};
var AuthFactory = function($scope, $rootScope, $state, $stateParams) {
var authToken = false;
var isAuthenticated = function() {
return authToken;
};
var login = function(state) {
//return (typeof(state) == 'string') ? $state.go(state) : $state.go("route1");
};
var logout = function() {
alert("You've been logged out");
$state.go("route1");
};
return {
isAuthenticated: isAuthenticated,
login: login,
logout: logout
};
};
////////////////////////
// END - FACTORIES
////////////////////////
////////////////////////
// BEGIN - DIRECTIVES
////////////////////////
////////////////////////
// END - DIRECTIVES
////////////////////////
app.controller("ContactAuthController", ContactAuthController);
app.factory("portalAPI", portalAPI);
app.factory("AuthFactory", AuthFactory);
})();
You can't inject $scope into a factory because there is none. Try var AuthFactory = function($rootScope, $state, $stateParams) { and use the $rootScope instead of $scope or pass the scope from the controller to your service.
https://docs.angularjs.org/guide/di
$scope: Controllers are always associated with a point in the DOM and so are
provided with access to the scope at that point. Other components,
such as services only have access to the singleton $rootScope service.

Categories

Resources