Not receiving response - ajax, codeigniter - angularjs

Ajax | angular controller,
$scope.counting=function(id){
if(id){
$.ajax({
type: "POST",
url: baseUrl()+'/index.php/site/count',
data:{"id":id},
dataType: "json",
contentType: 'application/json',
success: function(data) {
console.log(data);
},
error: function() {
console.log('no response');
}
});
}
Output
no response
Codeigniter controller,
public function count()
{
$input_data = json_decode(trim(file_get_contents('php://input')), true);
print_r($input_data); die;
}
I am getting the post data, but I am unable to receive any response.
Problem seems to be at the json_decode part, but it looks fine.
View,
<li ng-click="counting(<?php echo $value->id;?>);" class="count"><button type="submit" name="count"> <i class="fa fa-heart-o"></i></button></li>

From your controller send response back to js in json format using json_sncode().Because print_r() prints array in php, js will not recognize it. but you can see array in network tab of console as response.
public function count()
{
$id= $this->input->post('id');
$input_data = array('id'=>$id);
echo json_encode($input_data);
}

I have found a more legit solution to the problem.
I removed the button tag in the view,
<li ng-click="counting(<?php echo $value->id;?>);" class="count"> <i class="fa fa-heart-o"></i></li>
Doing so, I do get the response.
I figured, the 'type=submit' was posting the button value directly to the codeigniter controller, and also the 'li' was calling the ajax function, that was also posting the 'id' to the controller.
But, since the 'button type submit' was redirecting to the function count(or to say a new page), the response was unable to show as the response was coming to the previous controller function( or rather i should say previous page). Even removing the 'type=submit' would work in such case.

Related

handling an angular $http request in symfony controller

i want to send data from a twig view to a symfony controller using angular js $http method
this is my javascript
<script>
var app = angular.module('app',[]);
app.controller('ctrl',function($scope,$http) {
$scope.processForm = function() {
var val = $scope.libelle;
$http({
method: "POST",
url: 'http://localhost/symangular/web/app_dev.php/home',
headers: {
'Content-Type': 'application/json'
},
data:{libelle:val}
}).then(function (html) {
console.log(html);
});
}
});
</script>
and this is my controller
class DefaultController extends Controller
{
public function indexAction(Request $request)
{
$prod = new Product();
$form = $this->createForm(ProductType::class,$prod);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid() && $request- >isMethod('POST') && $request->isXmlHttpRequest()){
$em = $this->getDoctrine()->getManager();
$data = json_decode($request->getContent(), true);
dump($request->request->get('libelle'));
$request->request->replace($data);
$prod->setLibelle($request->request->get('libelle'));
$em->persist($prod);
$em->flush();
return new JsonResponse("good");
}
return $this->render('angulartestangularBundle:Default:index.html.twig',array('form'=>$form->createView()));
}
}
so when i execute i got an object in the console that i didn't understand it also i got nothing in database , did anyone have an idea about how to handle an
$http angular request in symfony controller
Object {data: "<script src="https://ajax.googleapis.com/ajax/libs…: 5 } ); })();/*]]>*/</script>↵</body>↵", status: 200, config: Object, statusText: "OK"}
In Symfony, a request considered as a XmlHttpRequest by reading request headers. The exactly code in Symfony is:
public function isXmlHttpRequest()
{
return 'XMLHttpRequest' == $this->headers->get('X-Requested-With');
}
So, when using angularjs or any javascript framework to make a XMLHttpRequest, you should add a header with X-Requested-With key and value = XMLHttpRequest. This header also required even if you're using fetch api. In your code abow, the request call should be:
$http({
method: "POST",
url: 'http://localhost/symangular/web/app_dev.php/home',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
},
data:{libelle:val}
})
If you don't want to add this header every time call $http function, you can add it as default config to $httpProvider:
angular
.module('yourModuleName', [])
.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
}])
;
For more details about $http configs and how to set default configs, look at Angularjs Documentation
Your approach is a little confused, and therefore very hard to debug.
its good practice (IMO) to separate your api endpoints from the controller action that renders the page. Coupling them together is going to seriously limit the extensibility of your application.
Its possible that you're failing one part of the complex if statement in your controller action; this is making it hard to debug.
Its also good practice when writing an api to provide the client with an idea of what went wrong on a call. (even if its only you accessing the api)
Looking at your code, it also looks like your getting mixed up in processing the request. Your'e validating the submission based upon it being a Product, and asking symfony to process the data on that basis, but then inside your submitted if statement, pulling out the data again..
You can still harness the symfony form validation by decoupling it and submitting this way.
/**
* If your using annotated routing do this, or make the equivelent in your yaml file.
* #Route("/api/product/create", name="api_product_create")
*/
public function productAction(Request $request)
{
$data = json_decode($request->getContent(), true);
if(!$data)
{
// youll want to handle this exception with a listener or somesuch so that it sends back a nice neat message to your client
throw new InvalidArgumentException('Invalid json');
}
$product = new Product();
// create your form as you did before.
$form = $this->createForm(ProductType::class,$product);
// this tells symfony to fill out the form, as if it was submitted conventionally.
$form->submit($data);
// now we can check for valid (you dont need to check submitted, as valid will do that anyway)
if($form->isValid())
{
// persist the new object
$em = $this->getDoctrine()->getManager();
$em->persist($prod);
$em->flush();
// create a new set of return data
$return = [
'status' => 'success',
'productId' => $product->getId(),
];
return new JsonResponse($return, 201);
}
// oops, something went wrong, find out and report it
$return = [
'status' => 'error',
'uri' => $request->getPathInfo(),
'errors' => (string) $form->getErrors(true, false),
];
return new JsonResponse($return, 400);
}
then, in your template, render the url to the endpoint properly.
url: {{ path('api_product_create') }},
this is just an example, and may not totally fit your usecase, but as you can see, once decoupled its much easier to find out what went wrong and where.
Useful resources:
https://knpuniversity.com/screencast/symfony-rest2/validation-errors-test (whilst payed to see the video, the transcript is free)
http://symfony.com/doc/current/form/direct_submit.html
thank you all for ansewring my question.. the informations were so helpfull .. otherwise the solution was to seprate the two actions in symfony controller and adding a request header to the $http method and it works very well .. thank u all

Angular not working in an ajax response

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>"
});

Including placeholder changes ngResource save() method from POST to GET

a really simple example. I have a RESTful api and I setup my resource the following way.
app.factory('apiFactory' , ['$resource', 'GLOBALS',
function($resource, GLOBALS){
return {
Discounts: $resource(GLOBALS.apiPath + 'discounts/:id', {id:'#id'}, {update:{method: 'PUT'}})
}
}
])
And then I call it in a Controller like so
var discountResponse = apiFactory.Discounts.save($scope.discount);
Everything works fine until I add '/:id' to my URL. I do this so that my delete method passes the id along. Like so 'discounts/6'.
The issue that I have is that as soon as I add the placeholder my save() method sends off a GET instead of a POST.
Request URL:http://local:8089/api/discounts
Request Method:GET
Status Code:200 OK
If I remove the placeholder I get
Request URL:http://local:8089/api/discounts
Request Method:POST
Status Code:200 OK
And everything works great, accept for the delete request, which now does not map the placeholder, as it no longer exists.
I have absolutely no idea why. I'm pretty new to $resource, so I am very sure I am not understanding something.
The answer was provided on a differently formulated question and I thought I'd share it.
return {
Discounts: $resource(GLOBALS.apiPath + 'discounts/:id', {id:'#id'} ,{
save: {
method: 'POST', url: GLOBALS.apiPath + "discounts"
},
update: {
method: 'PUT', url: GLOBALS.apiPath + "discounts/:id"
}
})
}
It would seem that for the save() to POST properly I had to define a path in the customConfig object. I'm not sure why this didn't work for me out of the box.
The answer was provided here. Many Thanks!
ngResource save() strange behaviour

Backbone Model and firing off to a different endpoint on attribute click event

I have a backbone model that fetches the data from the server,
var Post = Backbone.Model.extend({
url:"api/post"
});
on fetch it returns and populates the model like below
{
by: 1,
vote: 1,
text: "I am a post"
}
and I have a list view that renders these items into following html
<span className='vote'>
<i className='up-vote'></i>
1
<i className='down-vote'></i>
</span>
What I want to do is when user clicks on the upvote icon I want to fire a PUT request to the server whose endpoint looks like
"api/post/:id/vote"
What I am struggling with is, because the vote attribute is part of the Post model how do I fire off to this different endpoint using the existing Post model, as I have the vote attribute as a part of the Post model.
I think you have two options:
One would be to override Backbone.sync.
The other option is to use an AJAX request, which I think it's way simpler.
The code of your view for the second option would be something like this:
events : {
'click #up-vote' : 'sendPutRequest',
},
sendPutRequest: function() {
$.ajax({
url: 'api/post/' + this.model.get('id') + '/vote',
type: 'PUT',
contentType: 'application/json',
data: JSON.stringify(this.model.toJSON()),
success: function(result) {
// Do something with the result
}
});
}

Cakephp ajax request invalid url

i have a view page in which i have to load different views according to the option selected in a selecbox. But my problem is that the url to which ajax request is sent is not correct.
The correct path to be formatted is like this http://pc12/cakephp/users/getView but the ajax request goes to http://pc12/users/getview. What is my problem here?? My code is below:
jQuery('#ptype').change(function(){
var param = "id="+jQuery(this).val();
jQuery.ajax({
type: "POST",
url: "/users/getView",
data: param,
dataType: "text",
success: function(data){
if(data) jQuery('#profile_info').html(data); }
});
});
write complete address:
/AppName/Controller/Action/
you can use firebug for debug any ajax requests. it's very helpful.
Problem is the first front slash as I think.
url: "**/**users/getView",
in url: remove the first front slash(/) before users and it will work fine. I am using the same format without any problem. It will be like.
url: "users/getView",
it is easy and clear to use than your replacement: Html->url(array('controller' => 'users', 'action' => 'getView')); ?>

Resources