How to consume a rest service with angularJs from different project - javascript

I created a project which contains spring rest service that provides json format and angularJS Client which consumes the service and that work perfectly. Now I create another project which contains just the client (angularjs and html views) but I don't know how to access my rest service from this project.
This is what I have done :
angular.module('workflowService', ['ngResource']).
factory('Demande', function ($resource) {
return $resource('/rest/employee/:id', {}, {
'save': {method:'PUT'}
});
});
function EmployeeListController($scope, $location, Employee) {
$scope.employees = Employee.query();
$scope.gotoEmployeeNewPage = function () {
$location.path("/employee/new");
};
$scope.deleteEmployee = function (employee) {
employee.$delete({'id':employee.idEmp}, function () {
$location.path('/');
});
};
}
Any help please ?

You probably want to consume the REST service that your Spring back-end is providing. You should use the built-in Angular $http service to make calls to your back-end.
Make sure CORS is enabled on your back-end to allow different origins to make requests.

Related

angularjs, ui-router access to parameter at the beginning in the state url

I have a frontend web application written enterely in HTML5/JavaScript and the MVC is managed by AngularJS framework using UI-Router.
Now... I have the need to manage more customer with a single application using this pattern:
all customer have an applicationName (System.String)
the url to access into the application is [domain]/:applicationName/[view state] like: http://domain.com/MyName/login or http://domain.com/MyName/home/dashboard
so into the config function of Angular's bootstraping file I have to do something like this:
.state('home.dashboard', {
url: '/:applicationName/home/dashboard',
templateUrl: '/views/contents/dashboard.html'
});
so the problem is: applicationName is an unique name to retrieve the corrispondent applicationId (System.Guid) stored into the database (this applicationId is used to retrieve the corrispondent applicationName data from the database and so is used into all requests).
so the question: before to resolve the state url can I retrieve the applicationName and do the request to a rest api to get the corrispondent applicationId and store it in an angular service; then go to the state.
is it possible? and if yes, how can I do this?
thanks so much to everyone!
Lorenzo
I think you should use $locationChangeStart event in app run function where you can fetch the application Name from Database (using service/provider).
app.run(["$rootScope", "$location", "$window",function ($rootScope, $location, $window){
$rootScope.$on("$locationChangeStart", function (event, next, current) {
alert($location.$$path);
});
}])
This can be done in many ways. I have a recommendation though,
Have a default route and write a controller
Inside the controller please ensure to call the API and get the application id
Inside the controller you can do the $state.go()
See:
https://github.com/angular-ui/ui-router/wiki/URL-Routing#using-parameters-without-specifying-them-in-state-urls

Sending data (received from backend) from on html to another with angularJS

I feel like tons of people do this all the time, and yet I have been unsuccessful in finding similar examples.
I am getting data from the backend using angularJS ($http.post) to a controller in a javascript file, and presenting it in one html. The data is received after sending a search query from that html. Now, I want to "export" that data to another JS file and to present some of it again, in a new html. The problem is that I have access to that data only through the Search Controller during the searching session, and I probably need to store it somehow or send it to another controller/ JS file.
Unfortunately, I cannot use $cookies. Also, I am trying to avoid sending a new request through the server if I don't have to.
I have read a some about services in angular, however, I am new to angular (and UI in general), and for some reason was unable to implement this for my specific case.
Here is an example of the relevant controller, after getting a search request from the html page:
app.controller('SearchCtrl', ['$scope', '$http',
function($scope, $http) {
$scope.searchJSON = {
searchToken: [],
searchOption: []
$scope.sendSearch = function() {
//preparing JSON to send request to server
$scope.searchJSON["searchToken"] = this.search.searchToken;
$scope.searchJSON["searchOption"] = this.search.searchOption;
var json = $scope.searchJSON;
//sending and getting response (JSON object)
$http.post("http://some_host", json)
.success(function(response) {
$scope.collections = response.searchResults;
});
};
}]);
So the data I am interested in passing on to another JS file is in $scope.collections , which is a JSON file (I don't want use the same JS file for both html pages, so was hoping to call that data from a new controller in a new JS file).
Will appreciate any answers, leads, or similar examples from the web. Thank folks!
One possible way to solve this is by using sessionStorage/localStorage on $window. You can store your data there and after redirecting to another file, you can use it by invoking.
You are right to bring up services because that is how I would personally implement this. Create a service to handle the search request and also to store the result via promises:
angular.module('yourModule')
.factory('searchService', function($http, $q) {
var searchService = {
resultsPromise: null,
sendSearch: function(token, option) {
var dfd = $q.defer();
var json = {
searchToken: token,
searchOption: option
};
$http.post("http://some_host", json).then(
function(response) {
// resolve your deferred
dfd.resolve(response.data);
},
dfd.reject
);
this.resultsPromise = dfd.promise;
return dfd.promise;
}
};
return searchService;
});
Then in your current controller, just do:
app.controller('SearchCtrl', ['$scope', 'searchService',
function($scope, searchService) {
$scope.searchJSON = {
searchToken: [],
searchOption: []
$scope.sendSearch = function() {
searchService.sendSearch($scope.searchJSON.searchToken, $scope.searchJSON.searchOption);
};
Then in your other file, simply look at the currentResults of the same service:
app.controller('OtherCtrl', function($scope, searchService) {
if (searchService.resultsPromise) {
searchService.resultsPromise.then(function(results) {
$scope.results = results;
});
}
});
You can ditch the $http service and use $resource instead. From there you can use $cacheFactory as seen in this post: How to cache an http get service in angularjs
An alternative solution is http://jmdobry.github.io/angular-cache/ which works well with ngResource and can also easily be configured to sync to localStorage, so requests don't need to be re-done after page refresh.
`$resource('my/kewl/url/:key', { key: '#key' }, {
'get': { method: 'GET',
cache: $angularCacheFactory('MyKewlResourceCache', {
storageMode: 'localStorage' })
}
});`

signalR connection failing when trying to connect with cross domain hosted signalr service

I am trying to consume signalR on a website. SignalR is a self hosted service.
SignalR url: http://localhost8080:/signalr
Website is running # http://localhost:31775/
I am getting error on browser console
GET
http://localhost:31775/signalr/negotiate?connectionData=%5B%5D&clientProtocol=1.3&_=1442784297380
404 (Not Found)
This error tells me that proxy that the code below is trying to generate is using website url i.e. relative path. However I want to use absolute path where my signalR service is hosted.
AngularJS Factory
app.factory("signalRService", ['$', '$rootScope', function ($, $rootScope) {
var proxy;
var connection;
return {
connect: function () {
connection = $.hubConnection();
proxy = connection.createHubProxy('myHub');
connection.start();
proxy.on('addMessage', function (tags) {
$rootScope.$broadcast('addMessage', tags);
});
},
send: function () {
proxy.invoke('send');
},
};
}]);
I also added javascript reference for this.
<script src="js/jquery.signalR-2.0.3.min.js"></script>
To validate if my self hosting is running file. I checked http://localhost:8080/signalr/hub on browser
What you are missing is a bit of configuration of the proxy:
connection = $.hubConnection('http://localhost:8080/signalr');
How to generalize on that piece of code (the url could be an argument of your connect method, or whatever fits your Angular strategy) is up to you.

Angular Auth against Laravel backend

I am creating an app using Laravel and building a small internal API to connect to with an Angular frontend.
I have the auth working, but wanted to ensure that this is an acceptable way to log in a user, and to make sure everything is secure.
Sessions Controller:
public function index() {
return Response::json(Auth::check());
}
public function create() {
if (Auth::check()) {
return Redirect::to('/admin');
}
return Redirect::to('/');
}
public function login() {
if (Auth::attempt(array('email' => Input::json('email'), 'password' => Input::json('password')))) {
return Response::json(Auth::user());
// return Redirect::to('/admin');
} else {
return Response::json(array('flash' => 'Invalid username or password'), 500);
}
}
public function logout() {
Auth::logout();
return Response::json(array('flash' => 'Logged Out!'));
}
Laravel Route:
Route::get('auth/status', 'SessionsController#index');
Angular Factory:
app.factory('Auth', [ "$http", function($http){
var Auth = {};
Auth.getAuthStatus = function() {
$http({
method: "GET",
url: "/auth/status",
headers: {"Content-Type": "application/json"}
}).success(function(data) {
if(!data) {
console.log('Unable to verify auth session');
} else if (data) {
console.log('successfully getting auth status');
console.log(data);
// return $scope.categories;
Auth.status = data;
return Auth.status;
}
});
}
return Auth;
}
]);
I would then essentially wrap the whole app in something like an "appController" and declare the 'Auth' factory as a dependency. Then I can call Auth.getAuthStatus() and hide / show things based on the user state since this will essentially be SPA.
I realize I also need to hide the /auth/status URI from being viewed / hit by anyone, and was wondering how to do that as well. Kind of a general question but any insight would be greatly appreciated. Thanks.
Great question. I've answered this same question before so I will say the same thing.
Authentication is a bit different in SPAs because you separate your Laravel app and Angular almost completely. Laravel takes care of validation, logic, data, etc.
I highly suggest you read the article linked at the bottom.
You can use Laravel's route filters to protect your routes from unauthorized users. However, since your Laravel application has now become an endpoint only, the frontend framework will be doing the heavy lifting as far as authentication and authorization.
Once you have route filters set, that doesn't prevent authorized users from attempting to do actions that they are not authorized to do.
What I mean by the above is for example:
You have an API endpoint: /api/v1/users/159/edit
The endpoint is one of the RESTful 7, and can be used to edit a user. Any software engineer or developer knows that this is a RESTful endpoint, and if authorized by your application, could send a request with data to that endpoint.
You only want the user 159 to be able to do this action, or administrators.
A solution to this is roles/groups/permissions whatever you want to call them. Set the user's permissions for your application in your Angular application and perhaps store that data in the issued token.
Read this great article (in AngularJS) on how to authenticate/authorize properly using frontend JavaScript frameworks.
Article: https://medium.com/opinionated-angularjs/techniques-for-authentication-in-angularjs-applications-7bbf0346acec

Is it possible for ngResource to be called synchronously?

I currently have a factory which I'm using to retrieve a config file.
m.factory('clientConfig', function($resource) {
var r;
r = $resource('assets/config.json', {}, {
query: {
method: 'GET'
},
isArray: false
});
return r.query();
});
The config file is a json file which contains the location of a nodeJS server. In my local environment, the json file is
{
"serverURL": "http://localhost\\:3000"
}
When I start my app on the front page this is fine. The front page loads the clientConfig module, and any subsequent page just uses the clientConfig module like below without any problem
m.factory('House', function($resource, clientConfig) {
return $resource(clientConfig.serverURL + '/houses/:houseId',
...
The problem I'm running into is if I enter the site on a page that immediately wants to load data from the server. In that case, because clientConfig is not populated yet and still empty and this stuffs up my $resource(clientConfig.serverURL + '/houses/:houseId' call.
My question is is it possible to load up clientConfig synchronous or at least have my app not start until after clientConfig has been populated?
You can't. Since JavaScript is (mostly) single threaded, there are very very few blocking operations. XHR is not one of those. There is no way to make it synchronous.
Depending on your angular version, you can either $then or $promise it:
clientConfig.$then(function (){ do something})
or
clientConfig.$promise.then(function () {do something else})
You can't. $resource always returns asynchronous data. If you want synchronous data then use $http instead of $resource.
Change your service like this;
m.factory('clientConfig', function($http) {
var get = function {
$http.get('assets/config.json').success(function(data)){
return data.serverURL;
});
};
});
And call the service like;
clientConfig.get();

Categories

Resources