AngularJS Spring MVC Redirection with data binding - angularjs

I am new to AngularJS and the question may not be very smart.
I am trying to redirect to a new page with data-binding from Spring Controller.
My requirement is that when I click on a button/hyperlink on a page (say page 1), my Spring Controller performs business and determines which page to display (either page 2 or page 3). The data in the redirected page is populated from Spring Controller during redirection using query params.
My problem is that the page redirects just fine. But I am unable to retrieve the query params in AngularJS, though I can view them in the redirection request URL in browser (Google developer tools).
I have only added the relevant code :
Controller method called from first jsp page (say page1.jsp) to redirect to page2 (pageToRedirectTo.jsp)
In page1.jsp, there is a button that calls the method for page redirection along with form object.
<button ng-click="ctrl.onClickOfPage1ButtonRedirect ()">Page Redirect</button>
app.js
var angularApp = angular.module('angularApp',[]);
AngularJs Controller
this.onClickOfPage1ButtonRedirect = function(){
Page1Service.redirectToNewPage()
.then(
function(d) {
$scope.myVal = d;
var e1 = angular.element(document.getElementById("dir"));
e1.html(d);
$compile(e1.contents())($scope);
},
function(errResponse){
console.error('Error.');
}
);
};
AngularJS Service that sends request to Spring Controller
Page1Service.js
angularApp.factory('Page1Service', ['$http', '$q', function($http, $q){
return {
redirectToNewPage: function() {
return $http.post('/requestMappingUrlFromPage1')
.then(
function(response){
return response.data;
},
function(errResponse){
return $q.reject(errResponse);
}
);
}
};
}]);
Spring Controller
#RequestMapping(value="/requestMappingUrlFromPage1", method = RequestMethod.POST)
public ResponseEntity<Void> redirectToNewPage(){
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
List<ResponseDTO> responseDTO = new ArrayList<ResponseDTO>();
//Business logic to populate responseDTO list ....
String responseJson= new Gson().toJson(responseDTO);
UriComponentsBuilder b = UriComponentsBuilder.fromPath("/pageToRedirectTo");
UriComponents uriComponents = b.queryParam("responseDTOList", responseJson).build();
return new ResponseEntity<Void>(headers,HttpStatus.FOUND);
}
Now, when I get the response in Page1Service.js, it displays the response.data as the html content of the page being redirected to. In Google Chrome developer tools, I can see the query parameters :
responseDTOList:[{"parameter1":"123","parameter2":"Name","parameter3":false,"parameter4":false},{"parameter1":"123123","parameter2":"Name1","parameter3":false,"parameter4":false}]
Response received in Page1Service.js
Object {data: "<!DOCTYPE html>
↵<html ng-app="angularApp">
↵<head>
.......
↵</body>
↵
↵</html>", status: 200, config: Object, statusText: "OK"}
Is there a way to retrieve this data?
I have tried using $route.params, but it is undefined. Also, I am not using ng-route. Using $location is also not useful as all my pages are dynamically embedded in the custom dir tag in home page, so $location.absUrl() always gives the home page url.
Any suggestions are much appreciated. Thanks a lot in advance!!
I have added the browser header params that shows the response object in my Query Params. Angular response.data, however, displays just the HTML content, and I am unable to retrieve the query params.
Link to view the Browser headers : browser headers

The idea which pop in my head after examine your problem is that the one way of achieving your target is to convert angularJS page into Thymeleaf page. Its very simple to convert it and your all angularJS code will remain same. Please see Thymeleaf doc for this purpose.
Then simply you can get params in js script like this
<script th:inline="javascript">
/*<![CDATA[*/
var message = [[${message}]];
console.log(message);
/*]]>*/
</script>
Once you got your parms in Javascript then you can easily get into angularJS Controller.

If you are getting Page1Service.js response.data as HTML you can use JSON.parse to parse the content and get data.
it will be helpful to provide ans if you make it more clear "when I get the response in Page1Service.js, it displays the response.data as the html content of the page being redirected to."

I am not sure of it is possible to retrieve response data from query parameters in AngularJS.
However, I solved my problem by retrieving the query params in the GET request of the redirected page in Spring Controller. Then, I am sending it back to Angular Service via the HttpServletResponse header and retrieving it back in AngularJS.
Probably not the ideal solution, but that's the fix I could find in a short period without major restructuring of my code.
Spring Controller for redirection from page1 to page2
#RequestMapping(value="/requestMappingUrlFromPage1", method = RequestMethod.POST)
public ResponseEntity<Void> redirectToNewPage(){
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
List<ResponseDTO> responseDTO = new ArrayList<ResponseDTO>();
//Business logic to populate responseDTO list ....
String responseJson= new Gson().toJson(responseDTO);
UriComponentsBuilder b = UriComponentsBuilder.fromPath("/pageToRedirectTo");
UriComponents uriComponents = b.queryParam("responseDTOList", responseJson).build();
return new ResponseEntity<Void>(headers,HttpStatus.FOUND);
}
Redirected Page Controller mapping
#RequestMapping(value="/pageToRedirectTo",method = RequestMethod.GET)
public String getpageToRedirectTo(#RequestParam(required=false, name="responseDTOList")String temp, HttpServletRequest request,HttpServletResponse response) {
try{
if(temp!=null){
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//JSON from String to Object
List<ResponseDTO> objList = mapper.readValue(temp,TypeFactory.defaultInstance().constructCollectionType(List.class,ResponseDTO.class));
if(objList!=null){
String jsonList = new Gson().toJson(objList);
response.setHeader("responseDTOList", jsonList);
}
}
}catch(JsonMappingException jme){
logger.error("JsonMappingException : ", jme);
}catch(JsonParseException jpe){
logger.error("JsonParseException : ", jpe);
}
catch(IOException ioe){
logger.error("IOException : ", ioe);
}catch(Exception e){
logger.error("Error : ", e);
}
return "pageToRedirectTo";
}
Page1Service.js
angularApp.factory('Page1Service', ['$http', '$q', function($http, $q){
return {
redirectToNewPage: function() {
return $http.post('/requestMappingUrlFromPage1')
.then(
function(response){
var customResponse = {};
customResponse.responseDTOList= response.headers('responseDTOList');
customResponse.pageData = response.data;
return customResponse;
},
function(errResponse){
return $q.reject(errResponse);
}
);
}};}]);
AngularJS Controller
this.onClickOfPage1ButtonRedirect = function(){
Page1Service.redirectToNewPage()
.then(
function(d) {
$scope.responseList = d.responseDTOList;
$scope.myVal = d.pageData;
var e1 = angular.element(document.getElementById("dir"));
e1.html(d);
$compile(e1.contents())($scope);
},
function(errResponse){
console.error('Error.');
}
);
};

Related

Java, Struts 1.2, Json Angular JS - How can I get json response from action class to my Angular JS page?

I need a clarification on this below technology
Current technology:
Struts 1.2
Jsp
Java
AngularJS
Currently I am trying to migrate one of my jsp page to AngularJS page which is client req.
I am trying using below code to get json response, but I unable to get the json data in my jsp page.
Question:
1) How to get a json object from the response of action class in struts?
2) Currently :
Note: one of temporary way I able to get json object in jsp using session.setAttribute() and getAttribute.. but its not rite way to do it as I just getting all my table data and put in session. apart from this any way please help..
Code :
In jsp:
$scope.getDataFromServer = function() {
$http({
method : 'GET',
url : '/com/test/Browse.do'
}).then (function successCallback(response) {
var itemsDetails = JSON.parse(response);
$scope.person = response;
}).error(function(data, status, headers, config) {
});
};
**//The above response getting as object unable to get json object.**
In action class:
public void doExecute(ActionContext ctx) throws IOException,
ServletException {
PersonData personData = new PersonData();//[PersonData class available]
personData.setFirstName("Mohaideen");
personData.setLastName("Jamil");
String json = new Gson().toJson(personData);
ctx.forwardToInput();
}
I able to get the data using session attribute like below, but it is not rite way will make me to avoid struts action and also whole table data putting in session I not sure whether it will rite way or secure way.
var data1 = '<%=session.getAttribute("jsonobjtest")%>';
Can please help me out to get the rite way to implement with struts 1.2 and angularjs? if we cannot do it help me guide me the workaround how to achieve with angularjs?
Hie there from my understanding you want to get a json object from your Java backend
here is how i do http requests in AngularJs 1.5.11
(function () {
'use strict';
angular.module("myapp")
.controller("HelloController", function($scope,$http){
$scope.getDataFromServer = function() {
$http.get("/com/test/Browse.do").success(function(response,status){
//console.log(response,status); check your data
$scope.person = JSON.parse(response);
});
}
});

Returning response of spring controller to the angular js

I am trying to pass the response of my rest controller when a user tries to signup the form to my java script whether username is available or not basing upon the returned statement by the spring controller.However i tried to use model attribute in my spring controller.What is the way that i capture this in my js. From servlet perspective it is done as we have out.write how can it be done with spring.
My Spring controller
#RequestMapping(method = RequestMethod.POST,value = "/checkUserName", headers = "Accept=application/json")
public org.weber.nag.model.UserRegistration checkUserName(#RequestBody org.weber.nag.model.UserRegistration userReg, Model model) {
userDao.getAllUsers(userReg);
System.out.println(userDao.getAllUsers(userReg));
model.addAttribute("success", userReg);
return userReg;
}
AngularJS
var formData = {
'userName' : $scope.ctrl.newCustomer.userName
};
var response =$http.post('http://localhost:8081/Weber/user/checkUserName', formData);
response.success(function(data, status, headers, config) {
var cntrlMessage = $('#message');
message = cntrlMessage;
//alert(message);
alert(message);
$scope.list.push(data);
});
response.error(function(data, status, headers, config) {
alert( "User name already exists.");
});
updated Spring Controller
#RestController
#RequestMapping(value = "/user")
public class UserRegistrationControllerImpl{
#RequestMapping(method = RequestMethod.POST,value = "/checkUserName", headers = "Accept=application/json")
public String checkUserName(#RequestBody org.weber.nag.model.UserRegistration userReg, ModelMap model) {
userDao.getAllUsers(userReg);
System.out.println(userDao.getAllUsers(userReg));
String message = userDao.getAllUsers(userReg);
model.addAttribute("message", message);
return message;
}
}
I tried to hit the rest controller with $http it worked well how can i take the repose of my rest controller say user available/user not available back to my js as an alert.
Thank you
Your code seems to use Ajax to do the job done.
Then your Ajax success method is expecting to accept text response.
With that being said:
From your controller just return any String/text you want to display as a legitimate answer: user available/user not available
Annotate your controller with #ResponseBody that will tell Spring to return the String answer inside the HTTP response. So your Ajax success method will accept that HTTP response, with user available/user not available message.
Make sure you're actually getting that String in your js file using console.log
#RequestMapping(method=RequestMethod.POST,value="/checkUserName")
#ResponseBody
public UserRegistration checkUserName(#RequestBody UserRegistration userReg, Model model) {
userDao.getAllUsers(userReg);
System.out.println(userDao.getAllUsers(userReg));
model.addAttribute("success", userReg);
return userReg;
}

I send http post request with angular but it does not go to the asp.net mvc action and returns html layout tags

I am doing an angular application with asp.net mvc and i made a registration form with identity, I have layout and index mvc view which i just write in it ng-view tag and i inject html pages in it, I am doing a http post request from angular controller to mvc action method but the request does not go to the mvc action, whereas when i change th views to mvc views and make a templateUrl in angular map to mvc method it works well.
Can any one help me in this problem.
[HttpPost]
[AllowAnonymous]
public async Task<JsonResult> Register(RegisterViewModel model)
{
string message = "";
if (ModelState.IsValid)
{
var user = new ApplicationUser
{
FirstName = model.FirstName,
MiddleName = model.MiddleName,
LastName = model.LastName,
UserName = model.Email,
Email = model.Email,
UserStatus = UserStatus.Waiting
};
var result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
message = "Success";
}
else
{
AddErrors(result);
message = "InvalidEmail";
}
}
else
{
message = "Failed!";
}
return new JsonResult { Data = message, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
and this is my angular controller
MyApp.controller('RegisterController', ['$scope','$http',function ($scope, $http) {
$scope.message = '';
$scope.isFormValid = false;
//Check Form Validation
$scope.$watch('f1.$valid', function (newValue) {
$scope.isFormValid = newValue;
});
//Save Data
$scope.SaveData = function (data) {
$scope.submitted = true;
$scope.message = '';
if ($scope.isFormValid) {
$http({
method: 'POST',
url: '/Account/Register',
data: data
}).then(function (response) {
// check your response (if a success status code was resolved)
console.log(response.data);
}, function (error) {
// check your error response
console.log(error);
});
} else {
$scope.message = "Please Fill the blanks";
}
}
}]);
and this is my html page:
<div ng-controller="RegisterController">
<form name="f1" ng-submit="SaveData(user)" novalidate>
controls here
</form
1) Check your browser console for any javascript errors, if you have any, resolve them and try again!
2) Check you have the correct ActionMethodSelectorAttribute attribute ([HttpPost]) over your controller method and that your method name is spelt correctly.
3) Check that you have the correct path in your request.
4) Check you are sending the correct data to the controller!!!
5) Check that the method is public.
6) Check that you are authorised to access that controller/method.
7) Check that you don't have any duplicate method names with either, a) the same parameters and name (if your not using an ActionMethodSelectorAttribute, or b) the same names and method select attributes.
8) Remove all parameters from your method, put a breakpoint at the start of the method, and try making the request and see if it hits the breakpoint. If it works without parameters and not with, then you are not passing the correct required data into the method.
9) Make your request and check the response!! (example below):
// make your request
$http({
method: 'POST',
url: '/Controller/Method',
data: {
foo: bar
}
}).then(function(response) {
// check your response (if a success status code was resolved)
console.log(response);
}, function(error) {
// check your error response
console.log(error);
});
If you have a 404 then your method was not found, if you have a 500 then something blew up in your code, if you have a 401 then you are unauthorised etc... This is really useful to actually know what is going on with your request...
10) Check your application is running!

angular object post to laravel db

I have a json formatted post that arrives in the laravel api controller :
public function update($id) {
$post=Request::all();
return $post;
}
the post logs out to the console:
{id: 1, title: "Quiz1", description: "This is a quiz", level_id: 1, questions: Array[2]}
I would like to use the $post data in the laravel api controller to extract the data from the json object array and update my database.
The angular post is:
$scope.updateQuiz = function(quiz) {
$scope.loading = true;
$http.put('/admin/api/quiz/' + quiz.id, {
quiz
}).success(function(data, status, headers, config) {
$scope = data;
console.log($scope.quiz);
$scope.loading = false;
});
};
The code works in that it grabs the angular data and posts it to Laravel function and then posts back to the console in the angular app.
It is just the extraction of individual data that I cannot do.
This seems to work for individual posts but is rather cumbersome:
Angular:
$http.put('/admin/api/quiz/' + quiz.id, {
title:quiz.title
}).success......
Laravel Api:
$quiz->title = Request::input('title');
Wondering how I can avoid listing out all post objects.Must be something obvious I'm missing!?
Thanks.
Is this what you want ?
public function update($id) {
$post = Post::find($id);
if( !is_null($post ) ){
$post->title= $request->input('title');
$post->description= $request->input('description');
//And so on for all fields...
$post->save();
}
}
Note : it's not present in my example above, but you should validate the values received with the laravel validation. See http://laravel.com/docs/5.0/validation#form-request-validation
If your question was about how you redirect the http request to the controller, you should read the routing chapter of the doc : http://laravel.com/docs/5.0/routing
ex :
$app->group(['namespace' => 'App\Http\Controllers'], function($group){
$group->put('/admin/api/quiz/', 'YourController#update');
});

AngularJS Web Api HttpHandler Image Downloader

My AngularJS application is interacting with ASP.NET Web API to full fill the request which is working fine. it has an use case that allows user to download user specific secure PDF document. I have implemented this functionality as below
AngularJS:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
$scope.DownloadHandler = function (id, downloadURL) {
FileStreamManager.getPdf(id, downloadURL)
.then(function (result) {
// success
window.open(downloadURL + id, '_self', '');
},
function (result) {
$scope.errors = result.data;
});
};
Note : downloadURL is the Controller call like \ImageRepo\Get
Web Api Controller I have this implementation:
HttpResponseMessage response = new HttpResponseMessage();
// DB call to to build the URL
string fileName = "myLocation\Image\doc.pdf";
if (!fileProvider.Exists(fileName))
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
FileStream fileStream = fileProvider.Open(fileName);
response.Content = new StreamContent(fileStream);
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = fileName;
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
response.Content.Headers.ContentLength = fileProvider.GetLength(fileName);
return response;
Which is working fine. Due to the security issue, i was asked to implement this by using HttpHanlder which is pretty new to me. I have some question on the same.
Should my AngularJS ng-click calls to my .ashx handler directly instead of a Controller URL? Or Should this call route through Controller? How?
I have DB calls to build the image URL and update some the status. Can this be done in Handler itself?
How would i make sure my documents are secured while downloading?
Please help.

Resources