I'm trying to use the following...
.withHttpConfig({transformRequest: angular.identity})
but i always get undefined is not a function It does not seems to know what angular.identity is. Can anyone help?
full code:
angular.module('app.controllers.project', [
"app.factories.storage",
"app.factories.http",
"app.directives.typeahead",
"app.directives.projectDisplay",
"toaster"
])
.controller("projectController", ['$scope', '$rootScope', "$location",
"httpFactory", "filterService", "$stateParams", "toaster",
function ($scope, $rootScope, $location, httpFactory, filterService, $stateParams, toaster) {
var createProject = function () {
var resource = httpFactory
.withHttpConfig({transformRequest: angular.identity})
.post("project", data, {}, {'Content-Type': undefined})
.then(function () {
// do on success
console.log("done")
}, function () {
// do on failure
console.log("error")
});
etc
angular.identiy is a very simple function which just returns its arguments.
Here is the source code of it: https://github.com/angular/angular.js/blob/master/src/Angular.js#L379
What happens if you change your code from
.withHttpConfig({transformRequest: angular.identity})
to
.withHttpConfig({transformRequest: function(arg) { return arg; } })
Related
I have a function(uploadOne) inside fileUpload service that uses $q and returns a promise:
function uploadOne(some input)
{
var deferred = $q.defer();
if (everything is OK) deferred.resolve(some Data);
else deferred.reject(some error);
return deferred.promise;
}
I inject fileUpload service and call uploadOne function inside my controller:
.controller('myController', ['$scope', 'lessonsService', 'fileUpload',
function ($scope, lessonsService, fileUpload) {
//outside variable
$scope.lessonData = {};
fileUpload.uploadOne(some input data).then(function (some response data) {
console.log($scope.lessonData); //is undefined
lessonsService; //is undefined
}, function (err) {
//some code here
});
}])
The problem is that the variable declared outside the success function ($scope.lessonData) is undefined. In addition, I cannot even use my other service (lessonsService) there since it is also undefined! I've seen the same behavior in other posts but none of them help. What mistake am I making?
As you noticed the code above is a simplified version of my real code.
Here is my real code. I'm using ng-file-upload to upload a photo in my mongoDB database. When the image is stored in the database, the id of the image is returned from the server:
.controller('UserPanelPostsController', ['$scope', 'lessonsService', 'fileUpload',
function ($scope, lessonsService, fileUpload) {
//outside variable
$scope.lessonData = {};
$scope.submitLesson = function () {
fileUpload.uploadOne($scope.file).then(function (imgData) {
imgData; //is OK
console.log($scope.lessonData); //is undefined
lessonsService; //is also undefined
}, function (err) {
//some code here
});
};
}])
Here is my service:
.service('fileUpload', ['$resource', '$http', 'baseURL', 'Upload', '$q',
function ($resource, $http, baseURL, Upload, $q) {
var deferred = $q.defer();
this.uploadOne = function (file) {
Upload.upload({
url: baseURL + 'pictures',
data: {file: file}
}).then(function (resp) {
deferred.resolve(resp.data);
}, function (resp) {
deferred.reject(resp.status);
}, function (evt) {
//some code here
});
return deferred.promise;
};
}])
Here Demo Link
Here I attached the sample program for service call. In that Am facing the problem first time not getting the value properly.
1st time invocation:
2nd or more invocation:
May I know what was the problem? and help me to fix.
And why count executed first and datalength executed second?
$http.get is calling async by default. We have to use promise to make it sync. Use this updated code refer to Plunker:
var app = angular.module('myApp', []);
app.controller('myCtrl', ['$scope', '$location', '$filter', 'sampleService', '$http', function ($scope, $location, $filter, sampleService, $http) {
$scope.getCount = function () {
sampleService.getFile().then(function (data) {
var dt = data.PRTGetSlotsBySessionResult;
var count = $filter('filter')(dt, { "N": null });
alert(JSON.stringify(count.length));
});
}
}]);
app.factory('sampleService', ['$http', '$filter', '$q', function ($http, $filter, $q) {
return {
object: '',
makeRequest: function (url) {
// Create the deffered object
var deferred = $q.defer();
$http.get(url).then(function (resp) {
deferred.resolve(resp.data);
});
return deferred.promise;
},
getFile: function () {
if (!this.object) {
this.object = this.makeRequest("file.json");
}
// Return the myObject stored on the service
return this.object;
}
};
}]);
I tried to call function defined in a service.
var app = angular.module('title', ['flash', 'ngAnimate', 'ngRoute'],
function ($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
})
.service('getWidgets', function (globalServices, $http) {
var getData = function() {
var getWidgetUrl = globalServices.baseUrl + "admin/widget/list-text-widget";
return $http({method:"GET", url:getWidgetUrl})
.then(function(result){
return result.data;
});
};
return { getData: getData };
});
Calling section
var widget = getWidgets.getData()
.then(function (result) {
$scope.widgets = result;
$scope.$apply();
});
But it return an error getWidgets.getData is not a function.
What would be the root cause?
Change with this:
angular.module('dss')
.controller('widgetCtrl',
['$scope', '$compile', '$window', '$location', '$http', 'globalServices', 'getWidgets', 'Flash', '$timeout', '$sce', '$routeParams', widgetCtrl]);
function widgetCtrl($scope, $compile, $window, $location, $http, globalServices, getWidgets, Flash, $timeout, $sce, $routeParams) {
var widget = getWidgets.getData();
widget.then(
function (result) {
$scope.widgets = result; $scope.$apply();
});
}
EDIT: if you want an advice, use this syntax:
widgetCtrl.$inject = ['$scope', '$compile', '$window', '$location', '$http', 'globalServices', 'getWidgets', 'Flash', '$timeout', '$sce', '$routeParams'];
angular.module('dss').controller('widgetCtrl', widgetCtrl);
function widgetCtrl($scope, $compile, $window, $location, $http, globalServices, getWidgets, Flash, $timeout, $sce, $routeParams) {
var widget = getWidgets.getData();
widget.then(
function (result) {
$scope.widgets = result; $scope.$apply();
});
}
You are using a service and returning an object on its constructor.
Services get initialized as
new yourFunction and factories as yourFunction().
Switch it from service to factory and it will work.
EDIT: If you want to keep using a service, try this.
Note I changed the name of the service
function GetWidgetsService($http, globalServices){
this._$http = $http;
this._globalServices = globalServices;
}
GetWidgetsService.prototype.getData = function() {
var getWidgetUrl = this._globalServices.baseUrl + "admin/widget/list-text-widget";
// Angular $http() and then() both return promises themselves
return this._$http({method:"GET", url:getWidgetUrl}).then(function(result){
// What we return here is the data that will be accessible
// to us after the promise resolves
return result.data;
});
};
angular.module('yourModule').service('getWidgetsService', GetWidgetsService);
EDIT 2: For completeness, here is your fixed factory
angular.module('yourModule').factory('getWidgetsFactory', function ($http, globalServices) {
return {
getData: function () {
var getWidgetUrl = globalServices.baseUrl + 'admin/widget/list-text-widget';
// Angular $http() and then() both return promises themselves
return $http({method: 'GET', url: getWidgetUrl}).then(function (result) {
// What we return here is the data that will be accessible
// to us after the promise resolves
return result.data;
});
}
};
});
EDIT 3: HERE is a JSBin with your code working with my first solution.
Try this way
.service('getWidgets', function (globalServices, $http) {
return { getData: function() {
var getWidgetUrl = globalServices.baseUrl + "admin/widget/list-text-widget";
// Angular $http() and then() both return promises themselves
return $http({method:"GET", url:getWidgetUrl}).then(function(result){
// What we return here is the data that will be accessible
// to us after the promise resolves
return result.data;
});
};
};
});
Say i have the following factory:
app.factory("categoryFactory", function (api, $http, $q) {
var selected = null;
var categoryList = [];
return {
getList: function () {
var d = $q.defer();
if(categoryList.length <= 0){
$http.get(api.getUrl('categoryStructure', null))
.success(function (response) {
categoryList = response;
d.resolve(categoryList);
});
}
else
{
d.resolve(categoryList)
}
return d.promise;
},
setSelected: function (category) {
selected = category;
},
getSelected: function () {
return selected;
}
}
});
now i have two controllers using this factory at the same time. Because of this both controllers has to be notified when updated for this i attempted the following:
app.controller('DashboardController', ['$http', '$scope', '$sessionStorage', '$log', 'Session', 'api','categoryFactory', function ($http, $scope, $sessionStorage, $log, Session, api, categoryFactory) {
$scope.selectedCategory = categoryFactory.getSelected();
}]);
While my other controller looks like this:
app.controller('NavController', ['$http', '$scope', '$sessionStorage', '$log', 'Session', 'api', 'FileUploader', 'categoryFactory', function ($http, $scope, $sessionStorage, $log, Session, api, FileUploader, categoryFactory) {
$scope.categories = [];
categoryFactory.getList().then(function (response) {
$scope.categories = response;
});
$scope.selectCategory = function (category) {
categoryFactory.setSelected(category);
}
}]);
how ever when the NavController changed the value it was not changed in the DashboardController
My question is how can i either watch or in another way get notified when the value changes?
You can use an observer pattern, like so:
app.factory("categoryFactory", function (api, $http, $q) {
// the list of callbacks to call when something changes
var observerCallbacks = [];
// ...
function notifyObservers() {
angular.forEach(observerCallbacks, function(callback) {
callback();
});
}
return {
setSelected: function (category) {
selected = category;
// notify the observers after you change the value
notifyObservers();
},
registerObserver: function(callback) {
observerCallbacks.push(callback);
}
}
});
And then in your controllers:
app.controller('NavController', ['$http', '$scope', '$sessionStorage', '$log', 'Session', 'api', 'FileUploader', 'categoryFactory', function ($http, $scope, $sessionStorage, $log, Session, api, FileUploader, categoryFactory) {
// ...
// init
(function() {
categoryFactory.registerObserver(function() {
categoryFactory.getList().then(function (response) {
$scope.categories = response;
});
});
})();
}]);
This way, any time setSelected is called, it calls each callback that you've registered in observerCallbacks. You can register these from any controller since factories are singletons and they will always be in the know.
Edit: just want to add that I may have put the notifyObservers() call in the wrong area (currently in setSelected) and that I may be putting the wrong update call in the controller (currently getList) but the architecture remains the same. In the registerObserver, put whatever you want to do when the values are updated and wherever you make changes that you want observers to know about call notifyObservers()
You could follow dot rule here so that prototypal inheritance will get followed.
Basically you need to have one object inside your service that will have selected variable, And will get rid of getSelected method.
Factory
app.factory("categoryFactory", function(api, $http, $q) {
var categoryFactory = {};
categoryFactory.getList = function() {
var d = $q.defer();
if (categoryList.length <= 0) {
$http.get(api.getUrl('categoryStructure', null))
.success(function(response) {
categoryList = response;
d.resolve(categoryList);
});
} else {
d.resolve(categoryList)
}
return d.promise;
}
categoryFactory.setSelected = function(category) {
categoryFactory.data.selected = category;
}
categoryFactory.data = {
selected: null
}
return categoryFactory;
});
Controller
app.controller('DashboardController', ['$http', '$scope', '$sessionStorage', '$log', 'Session', 'api', 'categoryFactory',
function($http, $scope, $sessionStorage, $log, Session, api, categoryFactory) {
//this will provide you binding without watcher
$scope.selection = categoryFactory.data;
}
]);
And then use {{selection.selected}} on html part will update a value when changes will occur in selection.
Controller Code
'use strict';
angular.module('MyApp').controller('ArticleContribEmailController', [
'$scope', 'ArticleAppState', 'fbsUserDataService', 'contribEmailService',
function ($scope, ArticleAppState, fbsUserDataService, contribEmailService ) {
this.userChanged = function () {
if (fbsUserDataService.initialized && fbsUserDataService.user && ArticleAppState.page_data) {
// user has authenticated.
contribEmailService.initForm();
}
};
// watch for when user data is available, run userChanged.
$scope.$watch(function() { return fbsUserDataService.user; }, this.userChanged);
$scope.$watch(function() { return fbsUserDataService.initialized; }, this.userChanged);
}
]);
Service Code
'use strict';
angular.module('forbesArticleApp').service('contribEmailService', [
'$injector', '$route', 'ArticleAppState', 'fbsUserFormFactory', 'fbsUserDataService',
function initForm ($injector, $route, ArticleAppState, fbsUserFormFactory, fbsUserDataService) {
console.log("Hello world!");
}
]);
I only want to fire the contribEmailService.initForm() function from the call in my controller, but it is firing as soon as the page loads.
How do I set when the service function initForm() is called?
Here is the corrected service code:
'use strict';
angular.module('forbesArticleApp').service('contribEmailService', [
'$injector', '$route', 'ArticleAppState', 'fbsUserFormFactory', 'fbsUserDataService',
function($injector, $route, ArticleAppState, fbsUserFormFactory, fbsUserDataService) {
return {
initForm: function() {
console.log("Hello world!");
}
};
]);
The service function is a factory that will in turn return the actual service. So it will run the first time it is requested as a dependency. The way you had it written, in fact, contribEmailService would have been undefined within your function, because your factory didn't actually return anything.
Hope this helps!
controller:-
blogcontroller is controller name
app.controller('blogController', function($scope, $compile, $http, blogAuth, AppInfo, $location,$element){
$scope.blog_abuse = function(blog_id)
{
blogAuth.BlogAbuse(blog_id).then(function(response)
{
$scope.DetailblogList.is_abused = response.records.is_abused;
},function(error){
});
}
});
service:-
app.factory('AppInfo', function(){
return {
serviceURL:site_url
};
});
app.service('blogAuth', function($http, $rootScope, $q, AppInfo){
this.BlogAbuse = function(blog_id){
var deferred = $q.defer();
var pageObj ={"blog_id":blog_id};
$http.post(AppInfo.serviceURL+'blog/blog_abuse',pageObj).success(function(data){
deferred.resolve(data);
}).error(function(msg, code) {
console.log('error', code, msg );
});
return deferred.promise;
}
});