This question already has answers here:
How to get promise result using AngularJS
(2 answers)
Closed 3 years ago.
I'm trying to set textbox value based on the result of promise values when page has loaded. The values on textbox set only if I click on it and then out of it (just like blur event).
Controller
(function() {
'use strict'
var newPurchasingCardController = function($scope, $rootScope, $filter, $window, $location, $timeout, requestService) {
$scope.actionTitle = "";
$scope.gin = "";
$scope.fullName = "";
$scope.workEmail = "";
$scope.msg = "";
var getCurrentUserData = function () {
var dfd = new $.Deferred();
var queryUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/SP.UserProfiles.PeopleManager/GetMyProperties";
$.ajax({
url: queryUrl,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
success: onSuccess,
error: onError,
cache: false
});
function onSuccess(data) {
dfd.resolve(data);
}
function onError(data, errorCode, errorMessage) {
dfd.reject(errorMessage);
}
return dfd.promise();
}
var _init = function () {
$scope.actionTitle = "New Card Request"
var promise = getCurrentUserData();
promise.then(function (data) {
$.each(data.d.UserProfileProperties.results,function(i,property){
if(property.Key === "EmployeeNumber")
{
$scope.gin = property.Value;
}
if(property.Key === "FirstName")
{
$scope.fullName = property.Value;
}
else if (property.Key === "LastName") {
$scope.fullName += " " + property.Value;
}
if(property.Key === "WorkEmail") {
$scope.workEmail = property.Value;
}
console.log(property.Key+":"+property.Value);
});
}, function(error) {
console.log("An error has occurred trying to get employee information." + error);
});
}
$scope.$on('$viewContentLoaded', function(event)
{
_init();
});
}
angular.module('myApp').controller('newPurchasingCardController', ['$scope', '$rootScope', '$filter', '$window', '$location', '$timeout', 'requestService', createnewPurchasingCardController]);
}());
And in the html view I just have
HTML
<input ng-model="gin" type="gin" class="form-control" id="gin" placeholder="GIN">
<input ng-model="fullName" type="name" class="form-control" id="name" placeholder="Name">
<input ng-model="workEmail" type="email" class="form-control" id="email" placeholder="Email">
I have tried with viewContentLoaded but not working, what would be a good approach to accomplish this? Thanks.
You are mixing angularjs with Jquery and that causes all the problems.
Use $http service for get request : https://docs.angularjs.org/api/ng/service/$http#get
var getCurrentUserData = function () {
var queryUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/SP.UserProfiles.PeopleManager/GetMyProperties";
$http({
url: queryUrl,
method: "GET",
headers: { "Accept": "application/json; odata=verbose" },
cache: false
})
.then(function(response) {
$scope.gin = response.data.EmployeeNumber;
// here set scope variables directly
})
.catch(function(response) {
console.error('error', response.status, response.data);
})
.finally(function() {
console.log("finally ");
});
}
Related
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.
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;
});
I am using AngularJS v1.5.8, My requirement is when i click the Next button it'll display 'Processing...' inside button as text before complete the operation, i have included the $q with my services to get the asynchronous facility, but not working. please see my below codes.
Service
mainApp.factory('PINVerificationServices', ['$http', '$rootScope','$q', function ($http, $rootScope) {
return {
IsPermitted: function (param) {
return $q($http({
url: '/Api/ApiPINVerification/IsPermitted/' + param,
method: 'POST',
async: true
}));
}
};
}]);
Controller
mainApp.controller('PINVerificationController', function ($scope, $rootScope, $state, $window,$q, PINVerificationServices) {
$scope.SubmitText = "Next";
$scope.Next = function () {
$scope.SubmitText = "Processing...";
PINVerificationServices.IsPermitted($scope.PIN).then(function (result) {
$scope.SubmitText = "Next";
});
}
}
HTML
<div class="list-group list-group-sm">
<div class="list-group-item">
<input class="form-control" ng-model="PIN" placeholder="PIN" required id="PIN" name="PIN" type="text" />
</div>
</div>
<button type="submit" ng-click="Next()">{{SubmitText}}</button>
Try this:
return $http({
method: 'POST',
url: '/Api/ApiPINVerification/IsPermitted/' + param
});
Make below changes (from your requirement of nested $http).
In factory Use only $http, and no need of $rootScope as well, It should be like :
mainApp.factory('PINVerificationServices', ['$http', function ($http) {
return {
IsPermitted: function (param) {
return $http({
url: '/Api/ApiPINVerification/IsPermitted/' + param,
method: 'POST'
});
},
GetStudentInformationByPIN : function () {
return $http({
url: '/Api/ApiPINVerification/GetStudentInformationByPIN /',//your api url
method: 'GET'
});
}
};
}]);
In controller make use of $q.all() :
mainApp.controller('PINVerificationController', function ($scope, $rootScope, $state, $window,$q, PINVerificationServices) {
$scope.SubmitText = "Next";
$scope.Next = function () {
$scope.SubmitText = "Processing...";
$q.all([PINVerificationServices.IsPermitted($scope.PIN),
PINVerificationServices.GetStudentInformationByPIN($scope.PIN),
//other promises
]).then(function (result) {
if(result[0].data){
$scope.SubmitText = "Next";
}
if(result[1].data){
// studentdata response handling
}
});
}
}
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?)
So this is a bit complex, but I'll try to get into it, the best I can. In my config.js, I have:
.run(['$rootScope', '$location', 'UserService', 'CompanyService', function($rootScope, $location, UserService, CompanyService) {
$rootScope.globals = {};
$rootScope.$on('login', function(event, data) {
$rootScope.api_key = data.api_key;
CompanyService.get(data.user.company_id);
});
UserService.checkAuth().then(function(response) {
if(response.data.user) {
// Logged in user
$rootScope.$broadcast('login', response.data);
} else {
UserService.logout();
}
});
}]);
which basically checks to see if a user is logged in. If he is, we find out which user he belongs to with the CompanyService:
angular.module('mean').service('CompanyService', ['$http', '$rootScope', function($http, $rootScope) {
var company = this;
company.company_data = {}
company.getCompany = function() {
return company.company_data;
}
company.get = function (company_id) {
return $http({
url: '/api/v1/company/' + company_id,
method: 'GET',
headers: {
api_key: $rootScope.api_key
}
}).success(function(response) {
if(response.status === 'ok') {
company.company_data = response.company;
}
});
};
}]);
Later on in my code, I have a call that relies on the singleton CompanyService to do an API call:
$scope.index = function() {
LocationService.get(CompanyService.getCompany()._id, $routeParams.location_parent_id).then(function(response) {
if(response.data.status === 'ok') {
$scope.locations = $scope.locations.concat(response.data.locations);
}
});
}
if I refresh the page, however, sometimes this call gets executed before we've put data in the CompanyService singleton. How can I use promises to make sure that the LocationService doesn't happen until after we have data in the CompanyService singleton?
One way to do this is without changing your existing code too much would be to create a promise that is fulfilled when CompanyService has data. Note that this code doesn't deal with errors so that still has to be added...
angular.module('mean').service('CompanyService',
['$http', '$rootScope', '$q', function ($http, $rootScope, $q) {
var company = this;
company.company_data = {}
var initializedDeferred = $q.defer;
company.initialized = initializedDeferred.promise;
company.getCompany = function () {
return company.company_data;
}
company.get = function (company_id) {
return $http({
url: '/api/v1/company/' + company_id,
method: 'GET',
headers: {
api_key: $rootScope.api_key
}
}).success(function (response) {
if (response.status === 'ok') {
company.company_data = response.company;
initializedDeferred.resolve(); // reject promise on error?
}
});
};
}]);
$scope.index = function () {
CompanyService.initialized.then(function () {
LocationService.get(CompanyService.getCompany()._id,
$routeParams.location_parent_id).then(function (response) {
if (response.data.status === 'ok') {
$scope.locations = $scope.locations
.concat(response.data.locations);
}
});
});
}