How to call nest factory in Angularjs? - javascript

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;
});

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 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?)

Angular: Retrieve updated value in directive

I am filling my template named commentRecipe.html with data.
And i can call controller.add(1,2,'comment here') from inside the template.
The item gets updated in the db and returns my new result.
The Question is: How can i update ex mhRecipeId with the retrieved data.
var app = angular.module('myApp');
app.directive('mhCommentRecipe', ['$log', 'commentService', function ($log, commentService) {
var commentController = function () {
var that = this;
that.add = function (commentId, recipeId, commentText) {
if (recipeId && commentText.length > 0) {
var resultObj = commentService.add(commentId, recipeId, commentText);
}
};
}
return {
restrict: 'A',
templateUrl: '/app/templates/commentRecipe.html',
scope: {
mhRecipeId: '=',
mhCommentId: '=',
mhCommentText: '='
},
controller: commentController,
controllerAs: 'controller'
}
}]);
(function () {
app.factory('commentService', [
'$log', 'httpService', function ($log, httpService) {
var baseEndpointPath = '/myRecipes';
return {
add: function (commentId, recipeId, commentText) {
$log.debug(commentId, 'c');
var data = {
commentId,
recipeId,
commentText
}
var promise = httpService.post(baseEndpointPath + '/comment', data);
promise.then(function (response) {
// added
},
function (error) {
$log.error(error);
});
},
remove: function (commentId) {
if (commentId) {
var data = {
commentId,
recipeId,
commentText
}
data.commentId = commentId;
var promise = httpService.post(baseEndpointPath + '/removeComment', data);
promise.then(function (response) {
$log(response, 'removed response');
},
function (error) {
$log.error(error);
});
}
}
};
}
]);
})();
app.factory('httpService', ['$http', '$q',
function ($http, $q) {
return {
get: function (endpoint) {
var deferred = $q.defer();
$http.get(endpoint)
.success(function (response) {
deferred.resolve(response);
})
.error(function () {
deferred.reject('Failed to fetch response from endpoint');
});
return deferred.promise;
},
post: function (endpoint, data, config) {
var deferred = $q.defer();
$http.post(endpoint, data, config)
.success(function (response) {
deferred.resolve(response);
})
.error(function () {
deferred.reject('Failed to post data to endpoint');
});
return deferred.promise;
},
put: function (endpoint, data, config) {
var deferred = $q.defer();
$http.put(endpoint, data, config)
.success(function (response) {
deferred.resolve(response);
})
.error(function () {
deferred.reject('Failed to put data to endpoint');
});
return deferred.promise;
}
};
}]);
You place the values you want to send to the directive into a variable:
// in controller
that.mhRecipeId = whateverValueHere;
that.mhCommentId = whateverValueHere;
that.mhCommentText = 'comment text';
then on the directive in html you would put:
<mh-comment-recipe mh-recipe-id="controller.mhRecipeId" mh-comment-id="controller.mhCommentId" mh-comment-text="controller.mhCommentText"></mh-comment-recipe>
This will pass the variables into the directive for use.
Unless I misunderstood your question :)
Solved the issue and i am quite embarrassed to tell the solution!
In my view i just used ex: mhRecipeId when i should have used the controllers value.

AngularJS: transform response in $resource using a custom service

I am trying to decorate the returned data from a angular $resource with data from a custom service.
My code is:
angular.module('yoApp')
.service('ServerStatus', ['$resource', 'ServerConfig', function($resource, ServerConfig) {
var mixinConfig = function(data, ServerConfig) {
for ( var i = 0; i < data.servers.length; i++) {
var cfg = ServerConfig.get({server: data.servers[i].name});
if (cfg) {
data.servers[i].cfg = cfg;
}
}
return data;
};
return $resource('/service/server/:server', {server: '#server'}, {
query: {
method: 'GET',
isArray: true,
transformResponse: function(data, header) {
return mixinConfig(angular.fromJson(data), ServerConfig);
}
},
get: {
method: 'GET',
isArray: false,
transformResponse: function(data, header) {
var cfg = ServerConfig.get({server: 'localhost'});
return mixinConfig(angular.fromJson(data), ServerConfig);
}
}
});
}]);
It seems I am doing something wrong concerning dependency injection. The data returned from the ServerConfig.get() is marked as unresolved.
I got this working in a controller where I do the transformation with
ServerStatus.get(function(data) {$scope.mixinConfig(data);});
But I would rather do the decoration in the service. How can I make this work?
It is not possible to use the transformResponse to decorate the data with data from an asynchronous service.
I posted the solution to http://jsfiddle.net/maddin/7zgz6/.
Here is the pseudo-code explaining the solution:
angular.module('myApp').service('MyService', function($q, $resource) {
var getResult = function() {
var fullResult = $q.defer();
$resource('url').get().$promise.then(function(data) {
var partialPromises = [];
for (var i = 0; i < data.elements.length; i++) {
var ires = $q.defer();
partialPromisses.push(ires);
$resource('url2').get().$promise.then(function(data2) {
//do whatever you want with data
ires.resolve(data2);
});
$q.all(partialPromisses).then(function() {
fullResult.resolve(data);
});
return fullResult.promise; // or just fullResult
}
});
};
return {
getResult: getResult
};
});
Well, Its actually possible to decorate the data for a resource asynchronously but not with the transformResponse method. An interceptor should be used.
Here's a quick sample.
angular.module('app').factory('myResource', function ($resource, $http) {
return $resource('api/myresource', {}, {
get: {
method: 'GET',
interceptor: {
response: function (response) {
var originalData = response.data;
return $http({
method: 'GET',
url: 'api/otherresource'
})
.then(function (response) {
//modify the data of myResource with the data from the second request
originalData.otherResource = response.data;
return originalData;
});
}
}
});
You can use any service/resource instead of $http.
Update:
Due to the way angular's $resource interceptor is implemented the code above will only decorate the data returned by the $promise and in a way breaks some of the $resource concepts, this in particular.
var myObject = myResource.get(myId);
Only this will work.
var myObject;
myResource.get(myId).$promise.then(function (res) {
myObject = res;
});

AngularJS defer did'n return variable

I not understand why my function does not set my global variable. My code:
var localizeRegForm = {};
var handlerLocalDef = function(defer) {
var hash;
defer.then(
function(response) {
return hash = response.data;
},
function(err) {
showPopup(err);
}
);
return hash;
};
var initialized = function() {
console.log("localizeRegForm",localizeRegForm);
localizeRegForm = handlerLocalDef(Localization.getLocalizedDefer('regularform'));
console.log("localizeRegForm",localizeRegForm)
}
My console show:
localizeRegForm Object {}
localizeRegForm undefined
it's better to rewrite it:
var initialized = function() {
Localization.getLocalizedDefer('regularform').then(function(response){
localizeRegForm = response.data;
console.log("localizeRegForm",localizeRegForm)
});
}
and the question is not about AngularJS,
it's more about using defered object
use it like this
var deferred = $q.defer();
$http({
method: 'POST',
url: 'something',
data: data
}).
success(function(response, status, headers, config) {
deferred.resolve(response);
}).
error(function(response, status, headers, config) {
deferred.reject("");
})
return deferred.promise;

Categories

Resources