I have a button subscribe that should submit a post request via ajax to my controller for insertion to my table.
This is how my view look like:
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row">
<div class="col-md-8">
<div class="flash-message"></div>
<div class="card">
<div class="card-header">
<div class="level">
<span class="flex">{{$thread->creator->name}} posted:
{{$thread->title}}
</span>
#if(auth()->check())
#if($subscription)
<button class="btn btn-secondary" id="unsubscribe">Unsubscribe</button>
#else
<button class="btn btn-danger" id="subscribe">Subscribe</button>
#endif
#endif
#can('update',$thread)
Edit Thread
<form action="{{$thread->path()}}" method="POST">
#csrf
#method('delete')
<button class="btn btn-link" type="submit">Delete Thread</button>
</form>
#endcan
</div>
</div>
<div class="card-body">
{{$thread->body}}
</div>
</div>
..............
My app.blade:
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>
<!--jQuery/share.js -->
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha256-4+XzXVhsDmqanXGHaHvgh1gMQKX40OUvDEBTu8JcmNs=" crossorigin="anonymous"></script>
<script src="{{ asset('js/share.js') }}"></script>
<!-- Fonts -->
<link rel="dns-prefetch" href="//fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
<style>
body{
padding-bottom:100px;
}
.level{
display: flex;
align-items: center;
}
.flex{
flex: 1;
}
</style>
</head>
<body>
<div id="app">
#include('layouts.nav')
<main class="py-4">
#yield('content')
</main>
<flash message="{{session('flash')}}"></flash>
</div>
</body>
<style>
.btn-width{
min-width: 70px;
}
</style>
</html>
The code calling the button:
<script type="application/javascript">
$(document).ready(function(){
$('#subscribe').click(function(e){
e.preventDefault();
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: "{{route('subscription.store')}}",
method:'POST',
data: {
thread_id: "{{$thread->id}}",
},
success:function(response){
$('div.flash-message').html(response);
},
error:function(error){
console.log(error);
}
});
});
});
From what I could tell, there is no other element that shares the same id as my button. And, my button is not in a form submit so it should not be called twice. Inspecting dev tools shows no error and in the network tab, two requests are called identically with the same initiator.
So, I am kinda wondering why would this happen. Shouldn't an ajax post request submit the request once only?
I would really like to get to the bottom of this as most of the other similar issues have calling the submit twice while my code is only supposed to call it once. Instead, it makes two insertion to my db.
What else can I do to figure out the root cause of the issue?
Is it possible that your javascript is being loaded twice somehow? That would attach two identical listeners and send the request twice on a single click. If you put a console.log inside of the event handler, do you see that twice as well?
Also, apparently, .click adds a separate event listener for each element that matches the selector passed to the jQuery object, whereas .on only adds a single one.. What would happen if you did this instead?
$(document).ready(function () {
$("#subscribe").on("click", function(e) {
e.preventDefault();
$.ajaxSetup({
headers: {
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"),
},
});
$.ajax({
url: "{{route('subscription.store')}}",
method: "POST",
data: {
thread_id: "{{$thread->id}}",
},
success: function (response) {
$("div.flash-message").html(response);
},
error: function (error) {
console.log(error);
},
});
});
});
You can try these options:
(1) Use async: false in your ajax call to stop the execution of other code until you receive response of the current ajax call.
$('#subscribe').click(function(e) {
e.preventDefault();
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: "{{route('subscription.store')}}",
method: 'POST',
async: false,
data: {
thread_id: "{{$thread->id}}",
},
success: function(response) {
$('div.flash-message').html(response);
},
error: function(error) {
console.log(error);
}
});
});
OR
(2) You can use stopPropagation() method of the Event interface which prevents further propagation of the current event in the capturing and bubbling phases.
$('#subscribe').click(function(e) {
e.preventDefault();
e.stopPropagation();
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: "{{route('subscription.store')}}",
method: 'POST',
async: false,
data: {
thread_id: "{{$thread->id}}",
},
success: function(response) {
$('div.flash-message').html(response);
},
error: function(error) {
console.log(error);
}
});
});
OR
(3) Use a variable that stores the status of the request.
var isLoading = false;
$(document).ready(function() {
$('#subscribe').click(function(e) {
if (!isLoading ) {
isLoading = true; //make true when request starts
e.preventDefault();
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: "{{route('subscription.store')}}",
method: 'POST',
data: {
thread_id: "{{$thread->id}}",
},
success: function(response) {
$('div.flash-message').html(response);
isLoading = false; //make false when response is received
},
error: function(error) {
console.log(error);
isLoading = false; //make false when error is received
}
});
}
});
});
Have you tried giving return false? like this:
$(document).ready(function(){
let subscribeClick = function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: "{{route('subscription.store')}}",
method:'POST',
data: {
thread_id: "{{$thread->id}}",
},
success:function(response){
$('div.flash-message').html(response);
},
error:function(error){
console.log(error);
}
});
return false;
}
$('#subscribe').click(function(e){
e.preventDefault();
e.stopImmediatePropagation();
subscribeClick();
});
});
you are calling you function twice one in document ready and second on button click remover document
Related
I'm receiving a data from AJAX response and I'm trying to update a jQuery plugin with that value in the success callback:
$.ajax({
url: '/some/url',
type: 'GET',
dataType: 'json',
success: (data) => {
$(".my-rating").starRating('setRating', data.rating);
}
});
I'm using the star-rating-svg plugin to show ratigns (http://nashio.github.io/star-rating-svg/demo/). The problem is that I'm having an error:
Uncaught TypeError: $(...).starRating is not a function
However, this function works perfectly when is called outside AJAX callback. Do you know how to deal with this?
EDIT:
Larger piece of my code:
show.ejs
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="/star-svg/src/jquery.star-rating-svg.js"></script>
<link rel="stylesheet" type="text/css" href="/star-svg/src/css/star-rating-svg.css">
</head>
<body>
<div class="my-rating mb-1"></div>
<script>
function getUserRating() {
$.ajax({
url: '/some/url/rating',
type: 'GET',
dataType: 'json',
success: () => {
$(".my-rating").starRating('setRating', data.rating);
}
});
}
function webpageReady() {
if($(".my-rating").is(':visible')) {
$(".my-rating").starRating({
starSize: 20,
disableAfterRate: false,
callback: function(currentRating, $el){
$.ajax({
url: '/some/url/setRating',
type: 'POST',
data: {'rating' : currentRating}
});
}
});
getUserRating();
}
}
</script>
<script type="text/javascript">webpageReady();</script>
</body>
</html>
rating.js
router.get("/some/url/rating", function (req, res) {
Rating.findOne({'author.id': req.user._id}).populate("ratings").exec(function(err, rating){
if(err){
console.log(err);
}
else{
res.send({userRating : rating});
}
});
});
I had the same question, and I figured it out like this - I use jQuery StarRatingSvg v1.2.0:
callback: function(rating, $el){
$.post(
URL,
{ rating: rating, _token : "csrf_token" }
).done(function (resp) {
$el.starRating('setRating', parseFloat(resp.rating), false);
});
}
The callback function has two parameters: rating - the value set by a user when they click the stars, and $el - the rating element.
I hope it helps someone.
Here is simple demo for this plugin
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/star-rating-svg#3.5.0/src/jquery.star-rating-svg.js"></script>
</head>
<body>
<div class="my-rating"></div>
<script>
$(document).ready(function(){
$(".my-rating").starRating({
starSize: 25,
callback: function(currentRating, $el){
// make a server call here
}
});
});
</script>
</body>
</html>
Problem solved: In a footer there was another link to a jquery.
I'm working on a laravel web app, I'm relatively new to laravel so I'm not very familiar with the ajax tokens and such, but I believe I have set it up correctly.
Below is my Ajax code for a test page that I want to try and send data from.
<meta name="csrf-token" content="{{ csrf_token() }}">
<script type="text/javascript">
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
</script>
<script type="text/javascript">
$(document).ready(function () {
$('#btn').on('click', function (e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: 'testSend',
data: {
test: 'hello'
},
dataType: 'json',
success: function (response) {
alert(response);
},
error: function (data) {
console.log('Error:', data);
}
});
});
});
</script>
Here is my form:
<div class="flex-center position-ref full-height">
<div class="content">
<form action="testSend" method="post" enctype="multipart/form-data">
<button type="submit" id="btn"> submit</button>
</form>
</div>
And here is a simple route that I have setup just to test this:
Route::post('testSend', function (Request $request) {
return response()->json($request);
});
However when I go to check the network in chrome, the JSON Object is empty.
The empty JSON Object:
I'm pretty new to this, I have learned it but never really tried to create a web app until now. I have searched everywhere, but no one seemed to have the same problem, maybe they did but I just don't know.
The problem might just be a dumb mistake, but I really can't figure it out ):
Thanks.
Rather than passing Request instance try this:
return response()->json($request->all());
In a Laravel app, I need to update some data in the database after a button is clicked, without reloading the page, thus requiring ajax. No data needs to parsed, only a function in one of the controllers should be invoked, so it's the simplest kind of ajax request.
Based on this example, I set up the following, but nothing happens. No error, no response from the check alert('success!'), nothing.
QUESTION: why does nothing happen? Could it be that the Javascript is not recognized at al?
Head
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Routes - web.php
Route::post('/notificationsSeen','NotificationController#seen');
Controller - NotificationController.php
public function seen() {
$userNotifications = Notification::where('user_id',Auth::id())
->where('status','new')
->update(array('status' => 'seen'));
return;
}
View
<button type="button" id="notifications"></button>
<script>
$("#notifications").on('click', function() {
$.ajax({
type:'POST',
url:'/notificationsSeen',
data:'_token = <?php echo csrf_token() ?>',
success:function(data){
alert('success!');
}
});
});
</script>
EDIT: WORKING SOLUTION
Change the contents of the box above labeled "View" to the following:
<button type="button" id="notifications"></button>
<script>
(function ($) {
$(document).ready(function() {
$('#notifications').on('click', function() {
$.ajax({
url: '/notificationsSeen',
type: 'POST',
data: { _token: '{{ csrf_token() }}' },
success:function(){alert('success!');},
error: function (){alert('error');},
});
});
});
}(jQuery));
</script>
In your AJAX request, data is not a string. It is a key value pair. So use
data: { _token: '{{ csrf_token() }}' }
You shouldn't pass the csrf token like this:
data:'_token = <?php echo csrf_token() ?>',
You have to store it in a HTML meta tag:
<meta name="csrf-token" content="{{ csrf_token() }}">
Then automatically add the token to all request headers:
$( document ).ready(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$("#notifications").on('click', function() {
$.ajax({
type:'POST',
url:'/notificationsSeen',
data: {status: 'seen'},
success:function(data){
alert('success!');
}
});
});
});
Controller:
public function seen() {
$userNotifications = Notification::where('user_id',Auth::id())
->where('status','new')
->update(array('status' => request()->input('status')));
return ['success' => true];
}
I am new to React and Ajax and I am trying to make an api call to an Azure model but it seems to throw an error. For the time being I am using static data.
My code looks like this
example.js
var RecommendationInfo = React.createClass({
getInitialState: function() {
return {data: {}};
},
loadRecommendationInfo: function(e){
$.ajax({
async: true,
crossDomain: true,
url: 'http://ussouthcentral.services.azureml.net/workspaces/150de299226b41698270c2ddfbc6794b/services/604f4a58cc5e44daab413ecd3dd4dd5b/execute?api-version=2.0&format=swagger',
method: 'POST',
headers: {
'content-type': 'application/json',
'authorization': 'Bearer dSvR98YJPxUvGNvmVWaXcFIIBYmIA1ieSrDLde6qgpvUfV1uxq4/pT5EnfuTse1zwK1VHoOb4xg6gVVGmyFQsw=='
},
data:
{
'USER': 'user2',
'PARENT_SKU': '1',
'RATING': '1',
},
success: function(result) {
this.setState({data: result});
console.log(result);
}.bind(this)
});
},
render: function() {
return (
<div>
<h2><button onClick={this.loadRecommendationInfo} > Click me</button></h2>
</div>
);
}
});
ReactDOM.render(
<RecommendationInfo />,
document.getElementById('container')
);
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../shared/css/base.css" />
</head>
<body>
<div id="container">
<p>
If you can see this, React is not working right. This is probably because you're viewing
this on your file system instead of a web server. Try running
<pre>
python -m SimpleHTTPServer
</pre>
and going to http://localhost:8000/ .
</p>
</div>
<script src="../../build/react.js"> </script>
<script src="../../build/react-dom.js"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"> </script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"> </script>
<script type="text/babel" src="example.js"> </script>
</body>
</html>
There is an error which is coming from the above code in chrome
ERR_CONNECTION_TIME_OUT. I am not sure why is this happening. Please help.
Hey guys I need some help.
My problem is the error div is not displaying the content that I want it to appear in the success function of my AJAX request. I tried alerting the response and it returns true if user-name and password is correct and returns false if incorrect.
I don't know why its not working.
so this is my code
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body>
<div class="container" name="main-div">
<div id="error">
AA
</div>
<center>
<div name="login-div">
<h2>LOGIN PAGE</h2>
<form method="post" class="login_form">
Username: <input type="text" name="username"></br></br>
Password: <input type="password" name="password"></br></br>
<button type="submit" name="button_login" id="button_login">LOGIN</button>
</form>
</div>
</center>
</div>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script>
$(document).ready(function(){
$("#button_login").click(function(){
var data = $(".login_form").serialize();
$.ajax({
type: 'POST',
url: 'login_process.php',
data: data,
beforeSend: function(){
alert(data);
},
success : function(response){
//alert(response);
if(response=="true"){
$("#error").html("CORRECT USERNAME AND PASSWORD")
//window.location="home.php";
}else{
$("#error").html('<a>WRONG</a>');
});
}
}
});
});
});
</script>
</body>
</html>
Thanks in advance
There is an extra closing bracket in the script what you wrote. Try to open the page in the chrome and open the developers console to see the syntax error.
Login.html:44 Uncaught SyntaxError: Unexpected token )
I corrected the syntax as below
$(document).ready(function(){
$("#button_login").click(function(e){
e.preventDefault();
var data = $(".login_form").serialize();
$.ajax({
type: 'POST',
url: 'login_process.php',
data: data,
beforeSend: function(){
alert(data);
},
success : function(response){
//alert(response);
if(response=="true"){
$("#error").html("CORRECT USERNAME AND PASSWORD")
//window.location="home.php";
}else{
$("#error").html('<a>WRONG</a>');
}
},
error : function(response) {
$("#error").html('error'+ error);
}
});
});
});