Laravel Ajax Call through entire page - javascript

I am trying to run an Ajax post call through my entire application, it shall update the Navigation. On some pages it works but on others it does not, how can I fix this and make it global so to say.
I am using Laravel as a php Framework.
# Middleware group if user is logged in
Route::group(['middleware' => 'auth'], function () {
# Notifications
Route::group(['prefix' => 'notification', 'as' => 'notification.'], function () {
Route::post('number', ['as' => 'number', 'uses' => 'NotificationController#number']);
});
Route::group(['prefix' => 'relation', 'as' => 'relation.'], function () {
Route::get('show/{id}', ['as' => 'show', 'uses' => 'RelationController#show']);
});
});
in my layouts/app.blade.php I include the js file like this
<script src="{{ asset('js/liveUpdater.js') }}"></script>
#yield('javascript')
the liveUpdater ajax function
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
}
});
$.ajax({
url: 'number',
type: 'post',
success: function(data) {
$('#number-of-notifications').text(data.unread);
},
error: function(data) {
console.log('error number ' + data.data);
}
});
The Url http://localhost/myApp/public/notification/all returns a success message.
But an url for example like this http://localhost/myApp/public/relation/show/1 Returns an error message:
number
/myApp/public/relation/show
405
Method Not Allowed

You are prefixing the route with notification so your ajax request should point to notification/number:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
}
});
$.ajax({
url: 'notification/number',
type: 'post',
success: function(data) {
$('#number-of-notifications').text(data.unread);
},
error: function(data) {
console.log('error number ' + data.data);
}
});
Also I think aliasing (in the group) wouldn't help, so I think (for simplicity) you could have:
Route::group(['middleware' => 'auth'], function () {
# Notifications
Route::group(['prefix' => 'notification'], function () {
Route::post('number', 'NotificationController#number']);
});
});
Routing groups docs

You've to define route path and corresponding controller methods for every url paths like for relation/show and notification/all :
Route::group(['middleware' => 'auth'], function () {
# Notifications
Route::group(['prefix' => 'notification'], function () {
Route::post('show/{show}', 'NotificationController#show']);
Route::post('number', 'NotificationController#number']);
Route::post('all ', 'NotificationController#all']);
});
});

mistake in your request method in ajax. it should be type: "GET", OR in your web.php like Route::post('show/{id}' instead of Route::get('show/{id}'
your request method is not matching that why its throwing 405

Related

How to get to a laravel route using jquery ajax

I am trying to put to a method in a controller using ajax but I keep getting a 404 not found.
My JS:
var dataroomForm = $('#dataroomForm');
var dataroomId = $('#dataroomId').val();
var saveButton = $('.saveDataroom');
saveButton.click(function(e) {
var dataroomData = dataroomForm.serialize();
e.preventDefault();
console.log(dataroomData);
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: '/dataroom/' + dataroomId,
type: 'PUT',
data: {
'dataroom': dataroomData
},
dataType: 'json',
success: function (data) {
console.log(data);
},
error: function (request, error) {
alert("Request: " + JSON.stringify(request));
}
});
});
The route I am trying to trigger:
Route::put('dataroom/{dataroom}', ['as' => 'update', 'uses' => 'DataroomController#update']);
And update method (not really relevant I think but posting for complete view)
public function update(DataroomRequest $request, $id, MailService $mailService)
{
$dataroom = Dataroom::withoutGlobalScope(ActiveScope::class)->find($id);
if (is_null($dataroom)) {
\Flash::error('Dataroom niet gevonden!');
return redirect(route('admin.dataroom.index'));
}
$dataroom->fill($request->all());
$dataroom->save();
$dataroom->handleUploader($request, 'image');
if ($request->has('send_update')) {
$changes = $request->input('changes');
foreach ($dataroom->accounts as $account) {
$mailService->sendUpdate($account, $dataroom, $changes);
}
if (empty($changes)) {
$changes = 'Dataroom gewijzigd';
}
$dataroom->log($changes);
}
\Flash::success('De wijzigingen voor <strong>' . $dataroom->title . '</strong> zijn opgeslagen');
return redirect()->route('admin.dataroom.index');
}
In my network tab I get:
Request URL: http://website.nl.test/dataroom/26
Request Method: PUT
Status Code: 404 Not Found
And as response : exception: "Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException"
What am I doing wrong?
I don't see any issues in your code try using the command in your terminal php artisan optimize:clear in root folder this will flush/remove the application cache, route cache, and config cache altogether.

beforeSend: function() in fetch API

I am currently migrating the use of ajax to the fetch, however I am needing a parameter/function the Ajax native beforeSend: function(). I would like to perform the same action without requiring an implementation in fetch (a creation of a new class for example)
jQuery $.ajax structure:
$.ajax({
url: '...',
type: 'post',
data: {...},
beforeSend: function() {
// perform the action..
},
success: function(response, status, xhr) {
// receive response data
}
});
JavaScript fetch structure:
fetch('...').then((response) => {
return response.text();
}).then((data) => {
console.log(data);
});
How do I determine such a function without needing an implementation or creating a new class on fetch. Is there any means or only implementation? because of my searches I only found implementations like CustomFetch (Is there a beforesend Javascript promise) and others.
Solved problem!
No need to implement and/or create a new fetch class. Using only parameters as "function inside function". I hope you can help others!
function ipGetAddress(format) {
requestFetch = function() {
// perform the action..
console.log('** beforeSend request fetch **');
return fetch.apply(this, arguments);
}
requestFetch(`https://api.ipify.org?format=${format}`).then((response) => {
return response.json();
}).then((data) => {
console.log(data.ip);
});
}
ipGetAddress('json') // return local ip address..

How to pass data to the database with javascript and laravel

I'm creating this functionality where user can like a product and unlike it with javascript, if user likes the product it should add to the database and also if he unlike the product it should be deleted in database. Everything works fine in normal way but if I use javascript, the like button isn't working and either not adding anything in database same thing applies for unlike button. How can I make this work (like and unlike this should work in database too not changing the icons of like and unlike)?
Javascript
// Like product
function addToFavourites(productid, userid) {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
method: 'post',
url: `/product/like/${productid}`,
data: {
'user_id': userid,
'product_id': productid,
},
success: function () {
// hide add button
$('#addfavourites' + productid).hide();
// show delete button
$('#deletefavourite' + productid).show();
},
error: function (XMLHttpRequest) {
// handle error
}
});
// Unlike product
function deleteFromFavourites(productid, userid) {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
method: 'post',
url: `product/${productid}/unlike`,
data: {
'user_id': userid,
'product_id': productid,
},
success: function () {
// hide add button
$('#addfavourites' + productid).hide();
// show delete button
$('#deletefavourite' + productid).show();
},
error: function (XMLHttpRequest) {
// handle error
}
});
Route
Route::post('product/like/{id}', ['as' => 'product.like', 'uses' => 'LikeController#likeProduct']);
Route::post('product/{product}/unlike', 'LikeController#destroy')->name('product.unlike');
Blade File
#if($product->isLiked)
<div id="deletefavourite{{$product->id}}"onClick="deleteFromFavourites({{$product->id}}, {{ Auth::user()->id }})"> unlike </div>
#else
<div id="addfavourites{{$product->id}}" onClick="addToFavourites({{$product->id}}, {{ Auth::user()->id }})" > like </div>
#endif
How I add to favorite
public function likeProduct($id)
{
if(Auth::check()){
$this->handleLike(Product::class, $id);
return redirect()->back();
}
else{
return redirect()->route('login')
}
}
public function handleLike($type, $id)
{
$existing_like = Like::withTrashed()->whereLikeableType($type)->whereLikeableId($id)->whereUserId(Auth::id())->first();
if (is_null($existing_like)) {
Like::create([
'user_id' => Auth::id(),
'likeable_id' => $id,
'product_id' => $id,
'likeable_type' => $type,
]);
} else {
if (is_null($existing_like->deleted_at)) {
$existing_like->delete();
} else {
$existing_like->restore();
}
}
}
I think you have not completed curly braces of function check my code
function addToFavourites(productid, userid) {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
method: 'post',
url: `/product/like/${productid}`,
data: {
'user_id': userid,
'product_id': productid,
},
success: function () {
// hide add button
console.log($('#addfavourites' + productid));
$('#addfavourites' + productid).hide();
// show delete button
$('#deletefavourite' + productid).show();
},
error: function (XMLHttpRequest) {
// handle error
}
});
}
// Unlike product
function deleteFromFavourites(productid, userid) {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
method: 'post',
url: `product/${productid}/unlike`,
data: {
'user_id': userid,
'product_id': productid,
},
success: function () {
// hide add button
console.log($('#addfavourites' + productid));
$('#addfavourites' + productid).hide();
// show delete button
$('#deletefavourite' + productid).show();
},
error: function (XMLHttpRequest) {
// handle error
}
});
}
first you must check in network for see request and response from inspect element
this thing will make you can follow problem . you may have a problem with route so please
check the network during post request.
First of all I suggest change routes. I mean, use same pattern for both actions: like and unlike
Route::post('product/like/{id}', ['as' => 'product.like', 'uses' => 'LikeController#likeProduct']);
Route::post('product/unlike/{id}', 'LikeController#destroy')->name('product.unlike');
Then inspect what you see on server, log incoming data. It should help to understand, why you algorithm didn't work.
Second, you have to render both div's in your blade template
<div class="CLASS_SHOW_ITEM" id="deletefavourite{{$product- >id}}"onClick="deleteFromFavourites({{$product->id}}, {{ Auth::user()->id }})"> unlike </div>
<div class="CLASS_HIDE_ITEM" id="addfavourites{{$product->id}}" onClick="addToFavourites({{$product->id}}, {{ Auth::user()->id }})" > like </div>
You have to choose class by value of attribute $product->isLiked

Passing a query parameter from an AJAX get call to an express route

I'm playing around with a twitter API wrapper for Node right now and am trying to figure out how to pass a query parameter from an HTML form to an AJAX get request and have that parameter then passed into my Express route, rather than just having the form action go directly to the route.
Here's my HTML code
<form id="searchTerm">
Keyword:<input id="keyword" type="text" name="q" placeholder="Keyword">
<input type="submit">
</form>
My client-side Javascript
$(document).ready(function() {
$('#searchTerm').on('submit', function() {
$.ajax({
type: 'GET',
data: q,
url: '/search/tweets/term',
success: function(data) {
console.log(data);
},
error: function(error) {
console.log(error);
}
});
});
});
And then my Node.JS route:
// Search by keywords or phrases
app.get('/search/tweets/term', function(req, res) {
var q = req.query.q;
// Accesses the Twitter API and pulls back the respective tweets
client.get('search/tweets', {q: q, count: 100, lang: 'en', exclude: 'retweets'}, function(error, tweets, response) {
if(!error) {
res.send(tweets);
} else {
console.log(error);
res.status(500).send(error.stack);
}
});
});
I'm getting a "Query Missing Parameters" error message in my terminal whenever I input a value into the form, however. Not sure what I'm doing wrong.
UPDATE
Got it working via the following:
$(document).ready(function() {
$('#searchTerm').on('submit', function(e) {
e.preventDefault();
var q = $('#keyword').val();
$.ajax({
type: 'GET',
data: {q: q},
url: '/search/tweets/term',
success: function(data) {
console.log(data);
}
})
})
})
However, since I'm implementing e.preventDefault(), I'm losing the query parameters within my URL. Since I want to give users the ability to share URL's to specific keywords, is there any way to be able to keep these parameters intact in the URL while still getting the JSON sent client side? Or will have to just manipulate the JSON on the server side and have the data be rendered in via a template engine?
Try this
$(document).ready(function() {
$('#searchTerm').on('submit', function() {
$.ajax({
type: 'GET',
data: q,
url: '/search/tweets/term?q=',
success: function(data) {
console.log(data);
},
error: function(error) {
console.log(error);
}
});
});
});

Forbidden Error In JavaScript Ajax Call in CakePHP 3

I have Seen Similar Questions but I could not arrive at the solution. Please help on this code, I am new to javascript
My JavaScript Code :
function checkId(id_corpus){
var dataSet = {identity_number: id_corpus};
var requestUrl = appBaseUrl+'users/check-id-presence';
alert(id_corpus);
$.ajax({
type: "POST",
url: requestUrl,
data: dataSet,
success: function(result) {
if(result == false){
$('#ino').css('background-color', 'red');
$('#ino').css('color', 'black');
}
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(textStatus, errorThrown);
}
});
}
The Above JS code is called by the following CakePHP view:
$this->Form->input('identity_number', ['style' => 'background-color : black; color : #1798A5;', 'id' => 'ino', 'onkeypress' => 'checkId(this.val)']);
Following is the controller code
public function checkIdPresence()
{
$this->autoRender = false;
$id_corpus = $this->request->data['identity_number'];
$check = $this->Users->find()->where(['identity_number LIKE' => '%'.$id_corpus.'%']);
if((iterator_count($check)) > 0){
echo false; //Corpus Exists
}else{
echo true;
}
}
I am stuck in the "Forbidden Error", I would like to bring it to your notice that similar AJAX is being used by me for Image display(as shown below), it is not showing any error:
function fetch(user_id, photo, photo_dir)
{
var dataSet = {id: user_id};
var requestUrl = appBaseUrl+'users/admin-side-nav-details';
var imageUrl = 'http://localhost/media/images/users/photo/'+photo_dir+'/'+'100x100_'+photo;
$.ajax({
type: "POST",
url: requestUrl,
data: dataSet,
success: function(result) {
$('#display_info').html(result);
var image = "<img src ="+imageUrl+" />"
console.log(image);
$('#display_image').html(image);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(textStatus, errorThrown);
}
});
}
EDIT: My Auth Component setup :
public function initialize()
{
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'fields' => ['username' => 'email', 'password' => 'password']
]
],
'loginAction' => [
'controller' => 'Users',
'action' => 'login',
],
'authError' => 'Are you sure, you want to enter?',
'logoutAction' => [
'controller' => 'Users',
'action' => 'login',
],
]);
Check https://book.cakephp.org/3.0/en/controllers/components/authentication.html#handling-unauthenticated-requests. "If authenticator returns null, AuthComponent redirects user to the login action. If it’s an AJAX request and config ajaxLogin is specified that element is rendered else a 403 HTTP status code is returned."
It seems to me like you didn't specify any authorization scheme so according to https://book.cakephp.org/3.0/en/controllers/components/authentication.html#using-no-authorization "If you don’t use an authorization scheme, make sure to check authorization yourself in your controller’s beforeFilter or with another component."
You can make actions public (in beforeFilter or initialize) using:
// Allow all actions
$this->Auth->allow();
// Allow only the index action.
$this->Auth->allow('index');
// Allow only the view and index actions.
$this->Auth->allow(['view', 'index']);

Categories