I have a trouble with IE when ng-click is used in the button.
I want to reload the data from spring controller whenever user click on the button which is working fine in chrome but not in IE11.
Issue is when page is loaded data is displayed on the webpage, when Refresh Data button is clicked, it will reload the data by hitting to the spring controller which is not working in IE. In IE, when user click on a button, it is hitting the angular controller as well as service method also but not hitting the spring controller.But when developer tools is opened it is hitting the spring controller.
Example below:
html code:
<div ng-controller="loadingSampleCtrl">
<button class="btn btn-primary" type="button" ng-click="loadOrRefreshData()">Reload</button>
{{myData.empName}} /* This is printed in chrome as well as in IE with developer tools opened*/
</div>
js code:
myApp.controller('loadingSampleCtrl', function ($scope, MyService) {
$scope.loadData = function () {
$scope.loading = true;
MyService.testData().then(
function (response) {
alert("response back from spring controllerf");
if(window.navigator.msSaveOrOpenBlob){
$scope.IEBrowser = true;
$scope.myData = response;
/* $timeout(function() {
$scope.pdfName = response;
}, 0);*/
} else {
$scope.IEBrowser = false;
$scope.myData = response;
}
},
function (errResponse) {
$rootScope.showError("Internal error" + errResponse);
});
}
$scope.testData();
});
//service call
_myService.testData = function(){
alert("service call");//this alert is visible in IE
var deferred = $q.defer();
var repUrl = myAppURL+'/myDataToRead/getData.form';
$http.get(repUrl).then(
function (response) {
deferred.resolve(response.data);
},
function(errResponse){
deferred.reject(errResponse);
}
);
return deferred.promise;
}
spring controller:
#RequestMapping(value = "/getData", method = RequestMethod.GET,produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody
List<String> getMyData(HttpServletRequest request) throws Exception {
System.out.println("In MyDataController"); //not printed in IE when tested without developer tools
//logic here
//return statement
}
Any suggestions would be helpful.
i check you url var repUrl = yAppURL+'/myDataToRead/getData.form';, and i this the issue is you are not map controller with the path. you are only map your method with /getData. you need to use #RequestMapping annotation into your controller. you can refer below code :
#RestController
#RequestMapping("/myDataToRead")
Related
I am developing a spring+hibernate webapp for practicing translation skill from Russian to English.
In one of my jsp pages I am retrieving all the questions from database and placing them into a table with the following columns: text in Russian, field for user's translation, button for checking the result. The goal is to save user's input into database without refreshing the page. How can I do it?
I tried several options, but none of them worked for me.
I used the solution from Send javascript variables to spring controller in my project, but nothing happened at all.
Part of "firstPage.jsp" ("/first" path in the controller):
<head>
<title>Title</title>
<script>
function searchViaAjax(id) {
var tempId = id;
alert("Start");
$.ajax({
type : "POST",
url : "./search/api/getSearchResult",
data : {id:tempId},
timeout : 100000,
success : function(id) {
alert("success");
console.log("SUCCESS: ", id);
display(id);
alert(response);
},
error : function(e) {
alert("error");
console.log("ERROR: ", e);
display(e);
},
done : function(e) {
alert("done");
console.log("DONE");
}
});
}
</script>
</head>
<body>
<button onclick="searchViaAjax(1)">Simple button</button>
</body>
Controller class:
#Controller
public class DemoController {
#RequestMapping("/first")
public String getFirst(){
return "firstPage";
}
#ResponseBody
#RequestMapping(value = "/search/api/getSearchResult", method=RequestMethod.POST)
public String getSearchResultViaAjax(#RequestParam("id") Integer id) {
System.out.println("come to ajax"+ id);
return "hello";
}
}
The "Start" message gets printed, but other messages from searchViaAjax() don't. And controller method doesn't start.
You can pass id in controller as it is no issue in your 'id', and also you can skip value attribute in #RequestParam.
#ResponseBody
#RequestMapping(value = "/search/api/getSearchResult")
public String getSearchResultViaAjax(#RequestParam("id") integer id) {
System.out.println("come to ajax"+ id);
return "hello";
}
Specify the methodType
#RequestMapping(value = "/search/api/getSearchResult", methodType=RequestMethod.POST)
It is also a good practice to use wrapper instead of primitive
#RequestParam("tempId") Integer id
the problem is in your ajax url attribute.
It should be url : "./search/api/getSearchResult",
Root Cause:
When you are about to hit your controller, it construct the url like this
http://localhost:8080/search/api/getSearchResult
and hence such resource is not available and it causes 404 not found error.
In actual the url should be
http://localhost:8080/contextroot/search/api/getSearchResult
here contextroot refers your project name.
Now if you hit url ./search/api/getSearchResult then ./ refers the base url i,e localhost:8080/contextroot and the entire url will be constructed properly.
I would like to recommend you to create global variable in JavaScript say baseUri and assign./ into it.
<script>
var baseUri="./";
</script>
In your AJAX it becomes
url : baseUri+"search/api/getSearchResult",
Hope this will help
The code from user9634982 was fine, thanks to him. The problem was because I was using slim jQuery version so my browser was giving me "$.ajax is not a function" error. And I didn't see it for hours because I didn't know where to look :facepalm: Thanks again to user9634982 for discovering browser inspector to me :D After replacing slim version to usual it still didn't work because of spring security. I added _csrf token and all worked fine.
.jsp:
<meta name="_csrf" content="${_csrf.token}"/>
<meta name="_csrf_header" content="${_csrf.headerName}"/>
<script>
function searchViaAjax(id) {
var csrfHeaderName = "X-CSRF-TOKEN";
var csrfTokenValue;
var metaTags = document.getElementsByTagName('meta');
for(var i = 0; i < metaTags.length; i++) {
var metaTagName = metaTags[i].getAttribute("name");
if(metaTagName === "_csrf_header")
csrfHeaderName = metaTags[i].getAttribute("content");
if(metaTagName === "_csrf")
csrfTokenValue = metaTags[i].getAttribute("content");
}
$.ajax({
type : "POST",
url : "./addAnsweredQuestion",
data : {id:id},
timeout : 100000,
beforeSend:function(xhr){xhr.setRequestHeader(csrfHeaderName, csrfTokenValue);},
success : function(id) {
alert("success");
console.log("SUCCESS: ", id);
display(id);
alert(response);
},
error : function(e) {
alert("error");
console.log("ERROR: ", e);
display(e);
},
done : function(e) {
alert("done");
console.log("DONE");
}
});
}
</script>
Controller:
#PostMapping(value = "/addAnsweredQuestion")
public void getSearchResultViaAjax(#RequestParam("id") Long id) {
System.out.println("come to ajax"+ id);
}
I am using angularjs and springmvc in the application. My requirement is to hit the webpage(URL) and whatever response it returns(basically it returns html content of the webpage accessed through URL) i need to show on the html page.
Below is my code:
one.html
<div class="myDiv">
<table style="width:100%;height:100%;">
<tr>
<td ng-controller="getHTMLController">
<h1>HIT the URL and get the response</h1>
</td>
</tr>
</table>
{{htmlResponsedata}}
</div>
JavaScript
myApp
.controller("getHtmlDataController", [
"$scope", 'MyService',
function ($scope, MyService) {
MyService.fetch().then(function (response) {
$scope.htmlResponsedata = response;
}, function (errResponse) {
$scope.cancelModal();
$rootScope.showError(500, "Internal error");
});
_myServiceFactory.fetch = function () {
var deferred = $q.defer();
var repUrl = myAppURL + '/percentValues/' + '/getHtmlData.form';
$http.get(repUrl).then(function (response) {
console.log("response");
derred.resolve(response.data);
},
function (errResponse) {
console.error('Error while fetching data');
deferred.reject(errResponse);
}
);
return deferred.promise;
}
}
]);
Java
#RequestMapping(value = "/getHtmlData", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody String getHtmlData() throws Exception {
URL url = new URL("https://xyz/abc.com/values/reports");
HttpsURLConnection connection = ((HttpsURLConnection) url.openConnection());
connection.addRequestProperty("User-Agent", "Mozilla/4.0");
InputStream input;
input = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String msg;
while ((msg = reader.readLine()) != null)
System.out.println("--------------------"+msg);
return msg; //html code of the URL
}
}
Above is my entire code written using angularjs and springMVC. How to print the data returned by msg from java code on the oe.html page.I have used {{htmlResponsedata}} but the response is not printed. htmlResponsedata is the response i got and which i have set $scope.htmlResponsedata = response in the js code as shown above. Any suggestions as how to print the html response back on the screen?
In the View I have a linked button and there is java scripts to collect information from view and then post to the corresponding action 'GroupDeny'
#Html.ActionLink("Deny Selected", "GroupDeny", null, new { #class = "denySelectedLink" })
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$(document).on('click', '.denySelectedLink', function (e) {
//Cancel original submission
e.preventDefault();
var identifiers = new Array();
//build the identifiers . . .
var jsonArg = JSON.stringify(identifiers);
$.post('/LicenseAssignment/GroupDeny?licensePermissionIdentifiers=' + encodeURIComponent(jsonArg));
});
</script>
Then in the controller, the GroupDeny will update the DB and then
call RedirecToAction in order to refresh the view
public class LicenseAssignmentController : Controller
{
[HttpPost]
public ActionResult GroupDeny(string licensePermissionIdentifiers)
{
// changes the DB
return RedirectToAction("Index");
}
// GET:
public async Task<ActionResult> Index()
{
var model = get data from DB
return View(model);
}
Everything seems work as expected, The Index will be called after the RedirectToAction("Index") is executed, and the model is update to date their when I watch it during debugging, the only problem is that the page is not refreshed at all, that is to say the view still keep unchanged, but after I refresh the page manually (press F5), the data will be updated with the values from DB
We use AJAX when we don't want to navigate away from the page. Your $.post() is an AJAX request.
Since you want navigation add a form to your page
#using(Html.BeginForm("GroupDeny", "LicenseAssignment", FormMethod.Post))
{
<input type="hidden" value=""
name="licensePermissionIdentifiers"
id="licensePermissionIdentifiers" />
}
Now submitting this form will navigate
$(document).on('click', '.denySelectedLink', function (e) {
e.preventDefault(); // prevent link navigation
var identifiers = new Array();
//build the identifiers . .
// populate the form values
$("#licensePermissionIdentifiers").val(identifiers);
$("form").submit();
});
The RedirectToAction() returns to the browser a 302 Redirect to LicenseAssignment/Index then you hit the Index action.
Since you are using Ajax you will have to redirect on the return of your $.post call and change your GroupDeny to a JsonResult.
Something like this maybe:
JS
$.post('/LicenseAssignment/GroupDeny?licensePermissionIdentifiers=' + encodeURIComponent(jsonArg), function(data){
if(data.Success){
//redirect
window.location.reload();
}else{
//handle error
}
});
Controller Action
[HttpPost]
public JsonResult GroupDeny(string licensePermissionIdentifiers)
{
// changes the DB
return Json(new { Success = true });
}
Using Angular for UI and Spring in the backend secured with Spring security. Is it possible to define view page in the angularjs for request-mapping? For snippet below, on successful authentication, the page redirects to "/display" . Then, in the Spring controller I need to add a mapping for "/display" which returns the view "display"(html). Is it possible to include the mapping in the angular instead of spring??
$scope.login = function() {
authenticateUser($scope.credentials, function() {
if ($rootScope.authenticated) {
$location.path("/display");
$scope.error = false;
} else {
$location.path("/");
$scope.error = true;
}
});
};
I have the following action in ASP.NET MVC4
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
try
{
WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
WebSecurity.Login(model.UserName, model.Password);
// ?? Need some code here
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
I have the following code that calls this:
$('#article').on('submit', '#loginForm, #registerForm', function (e) {
e.preventDefault();
var $form = $(this);
var href= $form.attr('data-href');
$form.validate();
if (!$form.valid()) {
return false;
}
var data = $form.serializeArray();
$.ajax(
{
data: data,
type: 'POST',
url: href
})
.done(submitDone)
.fail(submitFail);
function submitDone(content) {
$('#article').html(content)
}
function submitFail() {
alert("Failed");
}
return false;
});
If the registration works I would like to force the whole web page to refresh. Is there
a way that I can send back a message from the actionmethod to the javascript to
tell it that the registration works and the javascript should refresh the whole
web page?
I did try return RedirectToLocal("/"); but this definitely does not work. What
this does is to return a new page and then have it populated in the #article DIV.
There is nothing that will automatically refresh the browser from the server.
To refresh the browser from the server you'll need to send something from the server to the client indicating that you want to refresh the page. You'll need to write the javascript to look for the indication to refresh the browser.
Client Code
function submitDone(content) {
var json = $.parseJson(content);
if(json.isSuccess) {
//Do something here
}
$('#article').html(json.content)
}
Server code
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
try
{
WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
WebSecurity.Login(model.UserName, model.Password);
// ?? Need some code here
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
}
}
// If we got this far, something failed, redisplay form
return Json(new {isSuccess = true, content = model});
}
I am unsure of what you are trying to accomplish by refreshing the page, if it's to clear out the form fields. The same could be achieved by using JavaScript. By using javascript instead of a page refresh you won't lose page state, such as error messages.
well i can think of a quick javascript trick to refresh a page on success like this
function submitDone(content) {
window.location.reload();
}
this will reload the page on the success.