laravel vue button gets route but couldn't access the controller - laravel

i have a vue button to shortlist a user. when i click the button it could access the route but not the controller. i have a regular button inside a form tag and set action to the same url. everything works fine. but the only problem is that it redirects to a different blank page after processing.
vue button #click method
<template>
<button class="button" #click="shortlistUser">Shortlist</button>
</template>
<script>
export default {
props:['userId'],
mounted() {
console.log('Component mounted.')
},
methods:{
shortlistUser(){
axios.get('/shortlist/' + this.userId);
}
}
}
</script>
web.php (this works)
Route::get('/shortlist/{user}', function (){
$employer = Auth::User();
$employer->candidates()->toggle([2]);
});
when i want to do the same via a controller, nothing happens.
Route::get('/shortlist/{user}', [Controllers\ShortlistController::class, 'index']);
controller
public function index(User $user)
{
$employer = Auth::User();
$employer->candidates()->toggle($user);
}

the problem exist in your axois call , userId send with undefined , be sure you send userId to the shortlist route . try to test your scenario by putting userid hard code like this : axios.get('/shortlist/2');

Related

Laravel + Vuejs: How to create a link to a blade template from Vuejs Component

I'm trying to keep Login and Register in blade. I used the default php artisan ui vue --auth.
Then keep the SPA in Vuejs with Vuetify.
App.vue
...sidebar containing link to register
<v-list-item link #click="register">
<v-list-item-action><v-icon>mdi-icon</v-icon></v-list-item-action>
<v-list-item-content><v-list-item-title>Register</v-list-item-title></v-list-item-content>
</v-list-item>
...
<script>
methods: {
register() {
axios.post('/register')
.finally( err => {
window.location = '/register';
})
},
}
</script>
If you click the register link, it keeps going to "/home" instead of "/register". Help please thanks.
instead of
window.location = '/register';
use this
window.location.href = '/register';

Laravel Livewire javascript code after model is load

I have one Laravel Livewire model open as bellow code
public function confirmItemAdd()
{
$this->resetValidation();
$this->confirmingItemAdd = true;
}
and my model window code in blade is
<x-jet-dialog-modal wire:model="confirmingItemAdd">
I have one select2 in model and want to set value of select2 on variable name $s2v
After search I findout that
$('.select2').val(s2v).trigger('change');
how can I set value of select2 on load on model?
Thanks
You can trigger a browser event from the livewire component and listen for that event and change the select2 value accordingly (assuming the select2 part is wire:ignored).
public $s2v = 'Test value';
public function confirmItemAdd()
{
$this->resetValidation();
$this->confirmingItemAdd = true;
$this->dispatchBrowserEvent('change-select2', $this->s2v);
}
in your layout file or with the stack in layout file you can listen for this event and trigger the change for the select2 as below,
<script>
$(window).on('change-select2', (e) => {
$('.select2').val(e.detail).trigger('change');
});
</script>
Note e.detail is the $s2v value passed from the livewire component.
And what validation error is giving to you? you are reseting the validation error before the dispatchBrowserEvent...seem that even by JS you are changing the select2 value the property doesn't
EDITED
Ok, first a have a particular issue with select2 rendering after each refresh and find this solution. In the component a have this:
public function hydrate()
{
$this->emit('select2');
}
and in blade parent or script section
<script>
$(document).ready(function() {
window.initSelectCompanyDrop=()=>{
$('#selectCompany').select2({
placeholder: '{{ __('locale.Select a Company') }}',
allowClear: true});
}
initSelectCompanyDrop();
$('#selectCompany').on('change', function (e) {
livewire.emit('selectedCompanyItem', e.target.value)
});
window.livewire.on('select2',()=>{
initSelectCompanyDrop();
});
});
</script>
If your issue with error bag persist, so you have to look into the kind of validation you're doing. In other case, I define global $message for a validation message but only works for $this->validate. Once I need redefine the validation, using Validator::make I have to create a new var $message for that inside the method

How to set url without refreshing the page (Laravel + vueJS)

I have a Laravel + VueJS app. I would like to change the url when the user selects a new year, for example.
The user in on the url idea/[IDEA_ID]/[YEAR] and changes year inside the page, so i want to set the url, but the rest of the work is done through axios call.
Here is how I work for now:
Route::get('idea/{n}/{m}', 'IdeaController#idea')->name('idea');
class IdeaController extends Controller
{
public function idea($id, $year)
{
$sql = "";
$array = DB::connection('ideas')->select( DB::connection('ideas')->raw($sql));
return view('ideas/idea', ['idea' => json_encode($array)] );
}
}
blade view:
#extends('template')
#section('content')
<div>
<div id="app">
<ideapage ideas="{{ $idea }}"></ideapage>
</div>
</div>
#endsection
And in my Vue view (ideapage), I have all the logic and only make axios requests.
The problem is that I want to change my url inside my Vue view, when the user changes the year for example.
Therefore I am wondering if I did the things well. Would it be a better idea to separate the components inside the laravel blade view? And how can I change only a section when the url changes?
I am not using VueRouter: the routes are in web.php only.
Thanks a lot in advance.
After a lot of thinking, I didn't change my architecture for now, and I only use history.pushstate when the year or idea changes
idea.vue
watch: {
idea: function() {
history.pushState({}, null, '/idea/'+this.idea +'/'+this.year)
},
year: function() {
history.pushState({}, null, '/idea/'+this.idea +'/'+this.year)
}
},

Vue: How to refresh new data?

I am using Vue Components in my blade file. Whenever I need to 'refresh' my customer object, I emit an event to the parent (shown below) and customer is refreshed and any props it passed to children will be shown with their updated values.
This is all well and good so far but I am now using some PHP values. I am passing a prop automatic-payments-enabled and it's using a php value. How can I have that value refresh after making an API call that changes it?
Blade file
<div id="app">
<Account
:customer="customer"
:automatic-payments-enabled={!! json_encode($customer->automaticPaymentsEnabled()) !!}
>
</div>
app.js
Vue.component('Account',
require('./components/Account.vue').default);
new Vue({
el: "#app",
data() {
return {
customer: null
}
}
mounted() {
this.getCustomer();
}
methods: {
getCustomer: function() {
//api call to server
this.customer = response.data
}
}
}
I suppose $customer is actually a Model. If so, you can use
$customer->fresh()->automaticPaymentsEnabled()

Why does my Vue-router component fails to reload except if loaded from router-link

I am using vue-router for route navigation in my laravel/Vue.js app. I have a Post component holding individual post of a blog, with router-link tags on excepts of post like so:
<router-link v-bind:to="'/post/' + post.id">
<p class="post_body">{{ post.body | truncate(100) }} </p>
</router-link>
post.id comes from props cascaded down from the parent component, Posts.
The router-link should redirect to another component i called single which will show the single post in details when clicked.
<template>
<div class="single">
<h1>{{ id }}</h1>
</div>
</template>
<script>
export default{
data(){
return {
id: this.$route.params.id
}
},
created(){
console.log(this.id);
}
}
</script>
The single post loads fine. However, when i try to reload/refresh the page, it goes blank. Why does the single component only load when i click from the post component but when i try to reload the page/component, it goes blank (the console also goes blank on refresh).
To expand on #LinusBorg's answer, with Laravel you would define a catch all route to your app.blade.php view file:
Route::get('/{path?}', 'AppController#index')->where('path', '.*');
The controller's action would simply return the view:
// AppController.php
public function index()
{
return view('app');
}
I would assume that you are using history mode but haven't set up the server appropriately.
When using history mode, your web server has to redirect calls to frontend routes (like when you refresh /page/1) to index.html, so your Vue app can boot up and take over the route handling.
Link to the documentation here

Resources