Angular not working in an ajax response - angularjs

ASP.NET MVC, AngularJs
I'm trying to use ajax to load some partials. I return the partial itself, from the controller, and I use $.html to load the partial. The problem is that the angular code inside the partial doesnt work. java script code that gets the partial.
function get(a) {
var div = $("#part");
var request = $.ajax({
url: "/Product/part",
type: "POST",
data: { a: a },
dataType: "html"
});
request.done(function (partial) {
div.html(partial);
});
request.fail(function (jqXHR, textStatus) {
alert("Request failed: " + textStatus);
});
}

So as we discourse in above comment yes you can append html in ajax success but there are some conditions if you directly assign your response object to .html or .append so it will not add anything but if your object is jquery object or any dom object then you can apply directly so it is depending on server side what you are sending in response.
Example:
Suppose my response has html string in request.data object
request.done(function (partial) {
div.html(partial.data); //partial.data has html string i.e "<div>test</div>"
});

Related

return json response from spring mvc to a html/angular view

I have a html/angular view which needs to get data from spring mvc controller which returns Json response.
Previously I used angular, getting json calling a REST url.
Not sure how to do the same when spring mvc controller returns a json response.
Thanks.
My sample code.
js
function sendMessage(message) {
$.ajax({
url : "/sample/push/" + message,
processData : false,
contentType : "text/html; charset=utf-8",
type : 'POST',
success : function(response) {
// get response
},
error : function(request, status, error) {
},
});
}`
controller
#RequestMapping(value = "/push/{message}")
public #ResponseBody String processResult(#PathVariable String message) {
// "your json String"
return pushService.pushMessage(message);
}
ajax call and spring MVC tutorial - link : this tutorial XD
Keep in mind some concepts as partial view, angular controller, angular service and how to make async call using the $http angular service.
Basically you create a Controller (js), a Service (js) and a partial View (html)
In the service you implement all data logic and rest api calls
In the controller you manipulate data retrieved using the service and prepare it to be presented in the partials
In the partial you "bind" (and it is shown to the user all data, actions, etc) the info in the controller

Handling file submit API response in angular

I have a form where a user uploads a file to my node server, does some stuff, and sends a JSON response.
I do not make the POST through the control, its via submitting a form. After my node code does some stuff, it sends this response succesfully.
res.json({
results: "TRUE",
file: rows,
column: pIndex,
rowCount: rows.length
})
Problem, i need to access this json response in my angular app. After a user submits form, they see raw json of this response and the app redirects to my endpoint: http://localhost:8000/upload-file
What do i do to access this response in my angular app without uploading file via controller($http.post)
I have no idea, im much new to javascript. Thanks!
Upload File with AngularJS
The template
<input type=file files-input ng-model="files" /><br>
<button ng-disabled="!files[0]" ng-click="upload()">Upload</button><br>
The Upload button becomes active after the file is selected.
The files-input Directive
app.directive("filesInput", function() {
return {
require: "ngModel",
link: function linkFn (scope, elem, attrs, ngModel) {
elem.on("change", function (e) {
ngModel.$setViewValue(elem[0].files);
});
}
};
});
The directive uses the ngModelController API to bind the selected files to a scope variable.
The upload() function
var vm = $scope;
var url = "API URL";
var config = { headers: {"Content-Type": undefined} };
vm.upload = function() {
//USE formData for Content-Type multipart/formdata
//var formData = new $window.FormData();
//formData.append("file-0", vm.files[0]);
//USE files[0] for binary upload
$http.post(url, vm.files[0], config)
.then(function(response) {
vm.result = "SUCCESS";
vm.data = response.data.data;
}).catch(function(response) {
vm.result = "ERROR "+response.status;
});
};
It is important to set Content-Type: undefined so that the AngularJS framework doesn't set the content type to application/json. The XHR send method will then set the content type according the type of the given object.
It is more efficient to send the file directly, but if content type multipart/formdata with base64 encoding is desired, use the formData API to create a formData object for the XHR API to send.
The DEMO on PLNKR.
This is because you aren't using the Angular controller. A regular HTML form, by default will attempt to make a URL params encoded POST request to the URL defined in the action="" attribute, or, if not defined, it will POST to the current URL. The result of the post is then simply spit out into the browser window.
Angular has a directive ngSubmit that is for intercepting this default behavior so that you can handle it in a controller:
<form ng-submit="mySubmitHandler()">
...
<input type="text" ng-model="formData.myField"/>
</form>
In your Angular controller you can now do whatever you wish. Typically you make a POST request using the $http provider:
function myController($scope) {
$scope.formData = {
myField: '',
};
$scope.mySubmitHandler = function () {
$http.post('/someUrl', formData).then(function(response) {
//handle the response from Node.js
});
};
}
The problem with this is that you are trying to upload a file. Trying to upload files with $http can be daunting. Your best bet is to use a 3rd party library to facilitate file upload in angular, such as ng-file-upload. It will come with it's own set of instructions that will allow you to handle the Node response inside of Angular.

AngularJS Spring MVC Redirection with data binding

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.');
}
);
};

Slim, Postman and AngularJs : $app->request->getBody() vs $app->request->post()

I'm a beginner. I've written a test application made of an AngularJs GUI on the client side and a PHP API on the server side.
This is the angular service handling the requests
myApp.factory('Book', ['$resource', 'API_URL', function($resource, API_URL){
return $resource(API_URL + '/books/:bookId', {bookId: '#bookId'}, {
get: { method: 'GET', isArray:true },
update: { method: 'PUT'},
save: { method: 'POST'},
delete: {method:'DELETE'},
});
}]);
When I submit a book from the Angular app I can catch the POST in Slim by using
$post_a = json_decode($app->request->getBody());
//$post_b = $app->request->post(); //this would be empty
When I use Postman and I perform a POST I can catch the POST in Slim by using
//$post_a = json_decode($app->request->getBody()); // this would be empty
$post_b = $app->request->post();
I don't get why there is this difference. Could you please explain?
Am I not meant to catch the post just with $app->request->post(); in both the cases? Why the post coming from Angular can be caught only with $app->request->getBody()?
The $app->request->post() method retrieves key/value data submitted in a application/x-www-form-urlencoded request. If the request uses a different content-type (e.g. application/json), you can retrieve the raw request body with the $app->request->getBody() method and decode it as necessary. Let me know if you have further questions.
You could still use
$post_b = $app->request->post()
in Slim.
As long as you call this REST service from html form (AngularJS) by passing the data as form value formatted instead of as JSON.
If in AngularJS you have the data in JSON format, you have to translate it first into form. Below is the example how to invoke this REST service:
Object.toparams = function ObjecttoParams(obj) {
var p = [];
for (var key in obj) {
p.push(key + '=' + encodeURIComponent(obj[key]));
}
return p.join('&');
};
$http({
method: 'POST',
url: url,
data: Object.toparams(myobject),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
myobject is the data in JSON format that is going to be created
Thanks Josh..Your answers works for me.
Steps to follow:
1.You need to send request in json format under raw tab like this:
{"username":"admin","password":"admin"}
2.You need to set Content-Type to application/json in the headers.
That's it and it will work.

how to get results of my webservice with jsonp?

I want to call one of my webservices via jsonp with angularjs.
When i call http://example.com/files?callback=JSON_CALLBACK directly in my browser, i got :
["folder1", "folder2"]
When i call from angularjs with :
$http.jsonp('http://example.com/files?callback=JSON_CALLBACK')
.success(function(data){
console.log(data);
$scope.folders = data;
});
console.log does not appear....
What am i doing wrong ?
Must my webservice return
JSON_CALLBACK(["folder1", "folder2"])
? Should i do it manually in my api ? browser don't do that automatically ?
What you are currently returning (["folder1", "folder2"]) is not valid JSONP. The JSON result must be wrapped by a javascript function call in order to be valid JSONP.
For example, when you use the URL like this:
http://example.com/files?callback=JSON_CALLBACK
Angular will replace the JSON_CALLBACK parameter with an angular function name (created internally), like:
http://example.com/files?callback=angular.callbacks._0
Your server would then need to be able to read that callback parameter and return the result like this:
angular.callbacks._0(["folder1", "folder2"]);
This is not an automatic mechanism, you need to implement that logic on your web server.
Try Using Following code snippet.
(function($) {
var url = 'http://example.com/files?callback=JSON_CALLBACK';
$.ajax({
type: 'GET',
url: url,
async: false,
jsonpCallback: 'jsonCallback',
contentType: "application/json",
dataType: 'jsonp',
success: function(data) {
console.dir(data);
},
error: function(e) {
console.log(e.message);
}
});
})(jQuery);
bmleite was right, I had to implement this logic on my API.
In my example, my server is made with Silex :
public function index()
{
$callback = $this->request->get('callback');
$files = $this->app['file.manager']->getList();
$response = new \Symfony\Component\HttpFoundation\JsonResponse();
$response->setData($files);
$response->setCallback($callback);
return $response;
}
And it works perfectly now. Thank you.

Resources