I'm uploading a file and I have validation logic in an MVC controller for the file. This attachment process can be used in the entire application; therefore, I need a directive.
I want to be able (once I click on the Upload button) to call an MVC controller from an Angular directive to eventually send the file to a web service.
Can someone please tell me how I can accomplish this?
I want to be able to use something like the below code inside my directive:
$http.post(ajaxUrl)
.success(function (status) {
if (status.Succeed) {
alert('file uploaded'
}
else {
alert(status.ErrorResult);
}
}
Did you consider to create and inject service to your directive?
(function () {
'use strict';
angular
.module('app')
.factory('service', service);
function service($http) {
var url = 'url';
var service = {
add: add
};
return service;
function add(data, callback, errorCallback) {
$http({
method: 'POST',
url: url,
data: data
})
.success(function (data, status, headers, config) {
})
.error(function (data, status, headers, config) {
});
};
}
})();
Call of the service in directive
service.add(data, function (status) {
});
Related
this whole story is on Angular 1.5.5.
so I have created a component and on its controller, on the $onInit function which basically contains this request
apphelper.readFromConfig($http).then(function (config) {...});
Iam getting a [$http:badreq] Http request configuration url must be a string error
the apphelper is a typical javascript closure function that several different applications use to get predefined ajax calls and it looks like this
var apphelper = function () {
var config;
return {
readFromConfig: function ($http) {
return $http.get(this.getConfig()).
then(function (response) {
return response.data;
});
},
setConfig: function (_config) {
config = _config;
},
getConfig: function () {
return config;
}
}
} ();
now here is the extremely odd part
the setConfig() is fired inside a factory
app.factory('session', function GetSession($http, $q) {
return {
getConfig: function (configuration) {
var defer = $q.defer();
if (!configuration) {
configuration = "default";
}
$http({
url: "/config/" + configuration,
method: "GET",
data: "{}",
headers: { 'Content-Type': 'application/json' }
}).success(function (data, status, headers, config) {
//staff
apphelper.setConfig("/config/" + configuration);
defer.resolve('done');
}).error(function (data, status, headers, config) {
console.log(data);
defer.reject();
});
return defer.promise;
}
}
});
and this factory is fired from the routeprovider
app.config(['$routeProvider',
function ($routeProvider) {
$routeProvider.
when('/:config', {
templateUrl: 'partials/components/my-map.html',
controller: 'MapController',
resolve: {
configData: function (session, $route) {
return session.getConfig($route.current.params.config);
}
}
});
}]);
All this story is for two reasons
first I got a directive that needs some values before the dom is initialized (thus the resolve) thingy
second I need to check by the time the page component gets loaded if there were any changes in the config service
As odd as it might seem it works. Now i cannot figure out how to unit test this thing. Any help will be appreciated
I'm pretty new with Angular and I'm stuck on this for a few days now :(
I have a web app (kind of portal with several web tools available).
I want to load some data from DB when the app being initially accessed and use the data in some controller (.i.e. load the data only once).
This is what I have by now:
Main app
var myApp= angular.module('MyApp',['ngRoute','ngTable','mpcApp','registerApp','forgotPasswordApp','tool1App','loginApp','userManagementApp','init']);
myApp.config(['$routeProvider','$locationProvider',function($routeProvider) {
$routeProvider.
when('/...', {
templateUrl: 'js/....html',
controller: 'tool1Ctrl'
})....
I also have myApp.run - but I will describe it later.
I've created different module for my factory:
(function (angular) {
var initApp = angular.module('init',[]);
initApp.factory('EndPoints', ['$http', function($http) {
var EndPointsList="";
return{
getList: function(){
$http.post("/getEndPoints", {
transformRequest : angular.identity,
headers : {'Content-Type' : undefined}
}).
success(function(data, status, headers, config) {
EndPointsList = data;
console.log(EndPointsList);
return EndPointsList;
}).error(function(data, status, headers, config) {
console.log("Failed to load end-points list");
});
return EndPointsList;
}
};
}]);
})(angular);
What I did next is injecting this factory into myApp.run:
myApp.run(['$rootScope', '$location', 'SessionIdService','EndPoints', function($rootScope, $location, SessionIdService,EndPoints) {
$rootScope.EndPoint= EndPoints.getList();
console.log("Current end-point: " + $rootScope.appEnv);
...
This is just not working! I don't see the print in console at all, and when I try to use the $scope.EndPoint in another controller in another module it appears to be empty.
Controller code:
var Tool1Controllers= angular.module('tool1App',[]);
Tool1Controllers.controller('toolCtrl', ['$scope', '$http','$rootScope', function ($scope, $http,$rootScope) {
console.log("Test: Controller end-point: " + $scope.EndPoint);
Please help! :(
The problem seems to be that you are returning a string before $http promise is fulfilled. You need to wait for the http response before returning data, or return the promise and let the consumers implement the outcome handlers.
Try updating your factory as follows:
initApp.factory('EndPoints', ['$http', function($http) {
return{
getList: function(){
return $http.post("/getEndPoints", {
transformRequest : angular.identity,
headers : {'Content-Type' : undefined}
});
}
};
}]);
And your run assignment as:
EndPoints.getList()
.success(function(data, status, headers, config) {
$rootScope.EndPoint= data;
}).error(function(data, status, headers, config) {
console.log("Failed to load end-points list");
});
UPDATE: An alternative to attaching data to the $rootScope is to have the factory cache the data and offer a method to return the data either from cache or from the remote endpoint if it hasn't already been cached:
initApp.factory('EndPoints', ['$http', '$q', function($http, $q) {
var endpoints = null;
return{
getList: function() {
return endpoints ?
// if data is already cached, return it
$q(function(resolve, reject) { resolve(endpoints); }) :
// otherwise fetch it from the service, cache it and return it
$http.post("/getEndPoints", {
transformRequest : angular.identity,
headers : {'Content-Type' : undefined}
}).then(function(data) { endpoints = data; return data; });
}
};
}]);
And now in your controllers, you can just inject the service and define outcome handlers for the getList promise:
.controller ...
EndPoints.getList()
.then(function(data) {
$scope.someVariable = data;
}, function(error) {
console.log("Failed to load end-points list");
});
...
Since factories are singletons, you can inject the Endpoints service into any number of controllers and the same cached data should be returned so that at most 1 call to the remote endpoint is made.
I am new to AngularJS.
Can I use mockjax in AngularJS by calling mock end points using $http services method get/post.
If not is there a way $http provides a way to create end points and call them?
For example
The MockService is something like this
$.mockjax({
url: '/sometest/abc',
type: 'post',
responseTime: 2000,
responseText: {
LoginSuccessful: true,
ErrorMessage: "Login Successfuly",
Token: "P{FsGAgtZT7T"
}
});
And the DataService that I have created has is as below.
'use strict';
//Data service
angular.module('app').factory('dataService',['$http', function($http){
var restCall = function (url, type, data, successCallback, errorCallback) {
$http({
method: type,
url: url,
data: data,
}).
success(function (data, status, headers, config) {
successCallback(data);
}).
error(function (data, status, headers, config) {
errorCallback(data)
});
};
return {
getTemplate: function (success, error) {
restCall('/sometest/abc', 'GET', null, success, error);
}
};
}]);
And the controller is below as
angular.module('App').controller('mainCtrl', ['$scope', 'trackService', 'dataService',
function ($scope, TrackService, ds) {
ds.getTemplate(function (data) {
//do some calculation
}, function () {
console.warn('Something is not right');
});}]);
I want know that is this the correct way of using the $http, or something else should be done.This is something I am trying to achieve in the actual code, but not in Unit test using jasmine.
I had to do this recently and I found that using Angular's built-in stuff (angular-mocks) was pretty easy.
Here's the basic idea: you include a separate module in your test harness which mocks out your requests, it's a basic URL matcher with either strings or regular expressions...
// in some other file that you include only for tests...
var myTestApp = angular.module('myApp', ['myApp']);
myTestApp
.config(function ($provide, $httpProvider) {
// Here we tell Angular that instead of the "real" $httpBackend, we want it
// to use our mock backend
$provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);
})
.run(function ($httpBackend) {
$httpBackend.whenGET('/some/url')
.respond(function (method, url, requestData, headers) {
// Do whatever checks you need to on the data, headers, etc
// Then return whatever you need to for this test.
// Perhaps we want to test the failure scenario...
return [
200, // Status code
{ firstname: 'Jordan' }, // Response body
{} // Response headers
];
});
});
Check the first link above to read my blog post on this.
I am new to AngularJS & working on a sample. In my sample app I have an MVC Web api (which returns some data from db) & it will be called from the Angular Services and returns the data to the Controller. The issue is I am getting the data in my Services success method properly but in my controller it always shows undefined & nothing is displayed in the view. Please see the code below:
My Controller code:
app.controller('CustomerController', function ($scope, customerService) {
//Perform the initialization
init();
function init() {
$scope.customers= customerService.getCustomers();
}
});
My Services code:
app.service('customerService', function ($http){
this.getCustomers = function () {
$http({
method: 'GET',
url: 'api/customer'
}).
success(function (data, status, headers, config) {
return data;
}).
error(function (data, status) {
console.log("Request Failed");
});
}
});
Please help me to fix this issue.
That's because your service defines the function getCustomers but the method itself doesn't actually return anything, it just makes an http call.
You need to provide a callback function in the form of something like
$http.get('/api/customer').success(successCallback);
and then have the callback return or set the data to your controller. To do it that way the callback would probably have to come from the controller itself, though.
or better yet, you could use a promise to handle the return when it comes back.
The promise could look something like
app.service('customerService', function ($http, $q){
this.getCustomers = function () {
var deferred = $q.defer();
$http({
method: 'GET',
url: 'api/customer'
}).
success(function (data, status, headers, config) {
deferred.resolve(data)
}).
error(function (data, status) {
deferred.reject(data);
});
return deferred;
}
});
Your problem is in your service implementation. You cannot simply return data since that is in the asynchronous success callback.
Instead you might return a promise and then handle that in your controller:
app.service('customerService', function ($http, $q){
this.getCustomers = function () {
var deferred = $q.defer();
$http({
method: 'GET',
url: 'api/customer'
})
.success(function (data, status, headers, config) {
// any required additional processing here
q.resolve(data);
})
.error(function (data, status) {
q.reject(data);
});
return deferred.promise;
}
});
Of course if you don't require the additional processing, you can also just return the result of the $http call (which is also a promise).
Then in your controller:
app.controller('CustomerController', function ($scope, customerService) {
//Perform the initialization
init();
function init() {
customerService.getCustomers()
.then(function(data) {
$scope.customers= data;
}, function(error) {
// error handling here
});
}
});
VERY late answer, but, Angular's $http methods return promises, so there's no need for wrapping everything into promise form with $q. So, you can just:
app.service('CustomerService', function ($http) {
this.getCustomers = function () {
return $http.get('/api/customer');
};
});
and then call the .success() or .error() shortcut methods in your client controller.
If you want to take it a step further and have a fully-fledged RESTful CustomerService without having to write this boilerplate, I'd recommend the restangular library, which makes all sorts of methods available to you - assuming of course your backend responds to HTTP verbs in the "standard fashion".
Then you could just do this:
app.service('CustomerService', function (Restangular) {
return Restangular.service('api/customer');
});
and call the methods Restangular makes available to you.
I use this for communication between Angular Web Data Service and Web Api Controller.
.factory('lookUpLedgerListByGLCode', function ($resource) {
return $resource(webApiBaseUrl + 'getILedgerListByGLCode', {}, {
query: { method: 'GET', isArray: true }
});
})
OR
.factory('bankList', function ($resource) {
return $resource(webApiBaseUrl + 'getBanklist_p', {}, {
post: {
method: 'POST', isArray: false,
headers: { 'Content-Type': 'application/json' }
}
});
})
I'm just starting out with Angular.js and I'm trying to figure out how to set up a factory that will show cached data and replace it with data retrieved from a REST service once it is received.
To test this out, I'm just hard-coding the "cached" data. Once the data is received, I want the $scope.directory variable to be updated with the latest data received from the server. I can either get it
Here's my factory code:
app.factory('directoryFactory', function ($http) {
var factory = {};
factory.directory = [{name: "Test", ext: "123"},{name: 'Bob', ext: "234"}];
init();
function init() {
$http({
method: 'GET',
url: '{restapiURL}'
})
.success(function (data, status, headers, config) {
factory.directory=data;
})
.error(function (data, status, headers, config) {
console.log('directory fail');
});
}
}
My Controller has the following code:
$scope.directory = directoryFactory.directory;
In my view, I use ng-repeat to list out all the people and their extensions.
I'd like the view to be updated once the data is received. What's the correct way to watch for factory data changes?
Your $scope.directory is promise that contains 2 handlers on success and on failure. Since $http is asynchronous, you don't know when response should come but "promise" will notify you about in case if you use then()
Here is example of POST but its the same flow:
factory:
myModule.factory('ajax_post', ['$http', function(_http) {
var path = 'src/php/data.ajax.php';
return{
init: function(jsonData){
var _promise= _http.post(path,
jsonData
,{
headers: {
'SOAPActions': 'http://schemas.microsoft.com/sharepoint/soap/UpdateListItems'
}
}
);
return _promise;
}
}
}]);
In controller:
var _promise= ajax_post.init(jsonData);
_promise.then(function (result) {
//do something with your result
},
function (error) {
alert(error.message);
}
);