Vue: How to refresh new data? - laravel

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()

Related

How to update root level component data

I can't get how to initialize a root component data field into a blade view. In particular:
app.js:
import { createApp } from 'vue'
const app = createApp({
data() {
return {
count: 0
}
}
});
blade view:
...html...
<script>
// how can I update count with a blade var (i.e. {{ $count }}) created in my controller?
</script>
In Vue2 actually it was pretty easier, but I'm getting so crazy to get this out that I'm supposing this pattern is not good at all...
Thanks in advance for your kind support.

how to access data ($count) from laravel controller to vue component

I want to access a variable $count from my controller and access it to a vue component (frontend). currently have this code on my controller:
public function index()
{
$count = User::where('created_at', Carbon::today())->count();
return view('user.index', compact('count'));
}
i am quite new to laravel and vuejs so please help me out. thank you!
Send count as a prop from blade to component
<your-component-name :count="{{ $count }}"></your-component-name>
And from your component, receive that prop
<template>
<div>
Count is {{ count }}
</div>
</template>
<script>
export default {
props: {
count: {
type: Number
}
}
}
</script>
To pass down data to your components you can use props. Find more info
about props over here. This is also a good source for defining those
props.
You can do something like:
<example :userId="{{ Auth::user()->id }}"></example>
OR
<example v-bind:userId="{{ Auth::user()->id }}"></example>
And then in your Example.vue file you have to define your prop. Then
you can access it by this.userId.
Like :
<script>
export default {
props: ['userId'],
mounted () {
// Do something useful with the data in the template
console.dir(this.userId)
}
}
</script>
the above question was answered in below question
Pass data from blade to vue component

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

What is the correct way to bring data from the controller to the vue.js? Laravel-vue.js

I haven't really used this method before and I'm confused where I'm going wrong.
I set the data in the controller, I added the mycourses entry but it's not coming through, everything else is coming in fine
$data['user'] = Auth::user()->load('userType');
$data['courses'] = StudentSchedule::where('instructor_id',Auth::user()->id)
->with('course', 'package.packageCourses', 'user', 'location')->get();
$data['mycourses'] = Course::all();
$data['locations'] = Location::all();
return view('home', $data);
After this I go to the blade and add this
<script>
const user = {!! json_encode($user) !!};
const mycourses = {!! json_encode($mycourses) !!};
const courses = {!! json_encode($courses) !!};
const locations = {!! json_encode($locations) !!};
</script>
Then this goes to the .js, but whats happening there is that its calling the vue
In the vue file I add this to the data()
courses: [],
mycourses: [],
locations: [],
In the vue file I add this to the mounted
this.courses = courses;
this.mycourses = mycourses;
this.locations = locations;
And the mycourses is giving me this error
Error in mounted hook: "ReferenceError: mycourses is not defined"
ReferenceError: mycourses is not defined
I added mycourses after all the other ones were added before, I have everything the same as the courses one and I'm still getting this error. What am I missing?
I'm not sure if this will be helpful or not, meaning perhaps there is a reason this method won't work given your circumstances.
I've found this method of setting/passing data to be pretty helpful. It's less overhead to have to parse in your blade templates (or wherever needed).
Controller
public function myFunction() {
...
$user = Auth::user()->load('userType');
$courses = StudentSchedule::where('instructor_id', $user->id)->with('course', 'package.packageCourses', 'user', 'location')->get();
$mycourses = Course::all();
$locations = Location::all();
// Verify the data is correct.
// dd($courses);
return view('example', compact('user', 'courses', 'mycourses', 'locations');
}
You can verify each is returning the value needed by checking what it's returning using dd().
If you have a vue component you are passing data to that exists in your blade template, you could do something like this to pass the data in as props
example.blade.php
<p>Example content...</p>
<p>Hello, {{ $user->name }}</p>
<example-component :courses="courses" :mycourses="mycourses"></example-component>
<p>...</p>
Now we have passed courses and mycourses to the view component. You can access them there:
<script>
export default {
name: 'ExampleComponet',
data() {
return {
//
}
},
methods: {
//
},
props: {
courses: {
type: Object,
required: true
},
mycourses: {
type: Object,
required: true
},
},
}
</script>
You'll need to update the property type for each of the props you pass in. Perhaps courses isn't an object, but rather a string.
I'm not sure if I've exactly solved your issue, but hope this helps get you in the right direction.

How to pass an object from Laravel to Vue without using props

I'm setting up some Vue Components in my Laravel 5.8 application, that require user information available through Auth::user(), most importantly, the api_token that I must use in my axios requests. I want to pass the Auth::user() object from Laravel to Vue in a secure and private method.
I initially passed the object as props, but I don't want private information on the object to be easily exposed using browser extensions such as Vue DevTools. Now, I've been searching for a way to define global variables inside the Blade Template and access them in Vue:
Pass data from blade to vue component
https://forum.vuejs.org/t/accessing-global-variables-from-single-file-vue-component/638
https://zaengle.com/blog/layers-of-a-laravel-vue-application
Based on those links above, it seems like what I need to do is set the variables to the window object, but I'm unsure on what I'm doing something wrong to achieve this. When I define the variable in the Blade Template, I can see the variable is assigning properly by doing console.log() but the problem comes when I try to use it in Vue.
app.blade.php
#if(Auth::user())
<script>
window.User = {!! json_encode(Auth::user()) !!}
console.log(window.User)
</script>
#endif
component.vue
<script>
export default {
data: function() {
return {
user: window.User
}
}
}
</script>
I've tried setting the data as window.User, this.User, and simply just User but it always comes up as undefined. What am I missing? Or is there any other/better way to do this?
Try the following Vue Component:
<template></template>
<script>
export default {
data: function() {
return {
user: window.User
}
},
created(){
console.log(this.user)
},
}
</script>
I could see the user data from the console.log in Vue component.

Resources