How to pass an array from Laravel controller to Vue.js component - laravel

I want to pass an array called hours from a Laravel controller to a Vue.js component but for some reason it's not working.
As you can see in the following code, I am trying to create dynamically the options inside a select that is located inside a component but for some reasons I see no options in that array.
In the view I created a <p> to check that the returning array from controller be correct and finally it is correct because in the view I am able to see the second value of the array.
But for some reasons I cannot visualize the values of the array inside the component.
This is my controller code:
$open_at = '00:00';
$close_at = '23:45';
$time = new DateTime($open_at);
$close = new DateTime($close_at);
while ($time < $close) {
$hours[] = $time->format('H:i');
$time->modify('+15 minutes');
}
return view('create')->with('hours', $hours);
This is my view code:
#extends('layouts.app')
#section('content')
<div class="container">
<div id="app">
<create-form :hours="hours"></create-form>
</div>
<p>
{{ $hours[1] }}
</p>
</div>
#endsection
This is code inside the template component:
<div class="form-group">
<label for="start">Start Hour:</label>
<select class="form-control" id="start">
<option v-for="hour in hours" :key="hour.id">
{{ hour }}
</option>
</select>
</div>
This is the my export_default:
export default {
props: ['hours[]'],
mounted() {
console.log('Component mounted.');
this.loadUsers();
this.loadRooms();
},
data: function() {
return {
users: [],
rooms: []
}
},
methods: {
loadUsers: function() {
axios.get('api/users')
.then((response) => {
this.users = response.data.data;
})
.catch(function(error) {
alert('noviva');
console.log(error);
});
},
loadRooms: function() {
axios.get('api/rooms')
.then((response) => {
this.rooms = response.data.data;
})
.catch(function(error) {
alert('noviva');
console.log(error);
});
}
}
}
I visualize the following warning in the console:
Property or method "hours" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.
Can help?

The definition of your props property doesn't match the name by which $hours is passed to the component
props: ['hours'],
And again you do not have id on hours the way you are constructing the hours[] in controller so the template will give another error when you try :key="hour.id
You must either construct the hours array in controller such that it has an id for every entry or (not recommended) you can use the index in the v-for loop as key
<div class="form-group">
<label for="start">Start Hour:</label>
<select class="form-control" id="start">
<option v-for="(hour, index) in hours" :key="index">
{{ hour }}
</option>
</select>
</div>
PHP arrays and objects can be passed to javascript/vue as props by json encoding them
//Using the blade helper #json
<div id="app">
<create-form :hours='#json($hours)'></create-form>
</div>
//OR using json_encode()
<div id="app">
<create-form :hours="{{ json_encode($hours) }}"></create-form>
</div>

Related

Vuejs: invalid expression: Unexpected token ':' in http://example.com

In my project using laravel 7. I'm using vue as frontend framework.
First in my controller I send only one attribute from my query into my template:
$sites = Site::with('users')->where('user_id', Auth::user()->id)->get();
// This is the part
$website_name = '';
if (sizeof($sites) == 0) {
// I fetch website attribute
$website_name = Auth::user()->website;
}
return view('axcess.sites.edit', [
'sites' => $sites,
'website_name' => $website_name // Send it into blade template
]);
In my blade template I send $website_name into component
<div class="row">
<axcess-sites-edit
:websiteName="{{ $website_name }}"
:isNewUser="{{ sizeof($sites) == 0 }}"
></axcess-sites-edit>
</div>
The full vue component is this:
<template>
<div class="col-md-8">
<form>
<div class="form-group">
<input class="form-control" :disabled="isNewUser" v-model="website" />
</div>
</form>
</div>
</template>
<script>
export default {
props: {
websiteName: String,
isNewUser: Boolean
},
data: function() {
return {
website: this.websiteName
}
}
}
</script>
Finally display the page as empty, in my console only display this error:
The problem comes from (:) symbol from http://example.com. There exists a solution for this to display into the input value.

Vue.js/Laravel: pass category id to Vue.js component

I'm using Vue.js with Laravel and facing a problem. I want to pass category id from the blade file to the Vue.js component as a prop. But don't know what is good practice and the right way for this.
I've defined the route something like this:
Route::view('/categories/{category}/edit', 'edit')->name('categories.edit');
and my edit.blade.php file is:
#extends('master')
#section('vue')
<div id="app">
<categories-edit :id=""></categories-edit>
</div>
#endsection
The Vue.js component code is:
<template>
<div class="container py-5">
<div class="row">
<div class="col-lg-12">
<div class="mb-3">
<label for="name" class="form-label">Name:</label>
<input type="text" v-model="formState.name" name="name" class="form-control" id="name" placeholder="Category Name" autocomplete="off">
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'CategoriesEdit',
props: ['id'],
data: function () {
return {
formState: {
name: '',
photo: ''
}
}
},
mounted() {
},
methods: {
loadInitialData: function () {
const self = this;
axios.get(``).then(function (response) {
}).catch(function (err) {
});
}
}
}
</script>
When I'm entering the URL in the web browser. I'm getting this error.
http://example.test/categories/1/edit
Output:
Undefined variable $category
Since you are using Route::view() you do not have the traditional way of getting route parameters and pass them to the view. Luckily you can always get these on the request object and there is a request() helper that makes it easier for Blade views.
<categories-edit :id="{{ request()->route('category') }}"></categories-edit>

how to access axios response in blade - laravel view

How to access axios result from vue component in blade file? I tried accessing {{value}} within 'app' div also. But the error still remains. I want to generate partial views based on the value of axios response.
IssueComponent.vue
<template>
<div>
<div class="form-group">
<label>Enter Accession No</label>
<input
type="text"
name="accession_no"
placeholder="Accession No"
class="form-control"
v-on:keyup.enter="getData()"
v-model="query"
/>
</div>
<div>
<button class="btn btn-info" #click.prevent="getData()">Check</button>
</div>
</template>
<script>
export default {
data() {
return {
query: "",
value: []
};
},
methods: {
getData: function() {
var self = this;
axios
.get("/issue-getdata", { params: { q: self.query } })
.then(function(response) {
self.value = response.data;
})
.catch(function(error) {
console.log(error);
})
.then(function() {
});
}
}
};
</script>
create.blade.php
<form action="/issue" method="POST">
<div id="app">
<issue-component></issue-component>
</div>
{{value}} ///////// Undefined constant error
<button type="submit" class="button-btn btn-success">Submit</button>
#csrf
</form>
Controller Method
public function getData(Request $request){
$input = $request->q;
$acsNo = preg_replace("/[^0-9]/", "", $input);
$acsNoIssued = Issue::where('accession_no', '=', $acsNo)->where('is_returned', null)->orwhere('is_returned', 0)->first();
return response()->json($acsNoIssued);
}
The Error
Facade\Ignition\Exceptions\ViewException
Use of undefined constant value - assumed 'value' (this will throw an Error in a future version of PHP) (View: D:\ProgrammingSSD\laragon\www\ulclibrary\resources\views\issues\create.blade.php)
You can't. Blade is rendered server side. By the time your vue component makes the request, that {{ $value }} is already parsed and is now a static part of your view.
What you could do is save the state (the information) in VUE, and read it using another VUE component that will display the info (instead of blade).
Guide for states in vue
https://vuex.vuejs.org/guide/state.html
<form action="/issue" method="POST">
<div id="app">
<issue-component></issue-component>
</div>
<display-component-value></display-component-value> // Vue component that reads the state you want
<button type="submit" class="button-btn btn-success">Submit</button>
#csrf
</form>

After Login the get route not worked in vue js Component in laravel

i want to load my provinces list in vue.js component , my code is worked , but when i login , show nothing in my list , here is my code
in my vuejs component :
<template>
<div class="row">
<div class="form-group required col-6">
<label for="province_id">Province</label>
<div class="col-12">
<select class="form-control" name="province_id[]" id="province_id" multiple v-model="province" style="height: 200px"
#change="getAllCities()">
<option v-for="province in provinces" :value="province.id">{{province.name}}</option>
</select>
</div>
</div>
<div class="form-group required col-6" v-if="cities.length> 0">
<label for="city_id">City</label>
<div class="col-12">
<select class="form-control" multiple="" name="city_id" id="city_id" style="height: 200px">
<option v-for="city in cities" :value="city.id">{{city.name}}</option>
</select>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
province: 'Select Province',
cities: [],
provinces: [],
flag: false,
}
},
mounted() {
axios.get('/api/provinces').then(res => {
// console.log(res);
this.provinces = res.data.provinces;
}).catch(err => {
// console.log (err)
})
},
methods: {
getAllCities: function () {
console.log()
axios.get('/api/cities/(' + this.province + ')').then(res => {
console.log(res);
this.cities = res.data.cities
}).catch(err => {
// console.log (err)
})
},
}
}
</script>
in Register Controller :
public function getAllProvinces()
{
$provinces=Province::all();
$response=['provinces'=>$provinces];
return response()->json($response,200);
}
my code work before login and show all provinces in my db , but after login there is nothin in my select , please help about that .
It happens because RegisterController uses guest middleware, you just don't pass the middleware when logged in, also it isn't good to me to use any method not related to the controller. Create new ProvinceController and define your method there it'll work
// this is RegisterController constructor
public function __construct()
{
$this->middleware('guest');
}
But if you somehow want to use your method exactly in the RegisterController then use except() method in constructor:
// add except
public function __construct()
{
$this->middleware('guest')->except(['getAllProvinces']);
}

VueJs component: can't attribute axios reponse to a component variable

I am new to VueJs with Laravel. I have a component called Event in which a 'read more...' link shoud trigger a function that fetch the event infos from the data base and store the in a variable withing this same component.
Here is the code for my component:
<template>
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">
<h5>
Title: {{ event.event_name }}
<span class="pull-right">
#click=getEventInfo(event.id)>Read more ...</a></span>
</h5>
<h5>publised by: {{ event.user.name }}
<span class="pull-right" v-text="timeFromNow(event.created_at)"></span>
</h5>
</div>
<div class="panel-body">
<p>{{ event.event_detail }}</p>
</div>
<div class="panel-footer">
<p>
<span>Event for: {{ event.event_to_whom }}</span>
<span>When: {{ dayOfDate(event.event_when_date) }} {{ event.event_when_date }} at {{event.event_when_time}}</span>
</p>
</div>
</div>
</div>
</template>
<script>
import moment from 'moment';
export default {
name: 'app-event',
props:['event'],
data() {
return {
eventInfo: {}
}
},
methods: {
timeFromNow(tmp) {
return moment(tmp).fromNow();
},
dayOfDate(d) {
let dt = moment(d, "YYYY-MM-DD");
return dt.format('dddd');
},
//event.id
getEventInfo(id){
let url = 'events/' + id;
axios.get(url)
.then((response) => {
console.log(response.data); //returns data
this.eventInfo = response.data;
console.log(this.eventInfo);//returns data
});
console.log(this.eventInfo); //returns nothing
}
}
}
</script>
The problem is when I click the 'read more...' link axios returns a response that I can check using console.log(response.data). Hovever when I console.log(this.eventInfo) outside the axios closure, it returns and ampty object.
Am I doing something wrong? Sorry if the question is too basic.
Thanks
L.B
You are printing logging the property before it is assigned a value.
The code below should resolve any errors
import moment from 'moment';
export default {
name: 'app-event',
props:['event'],
data() {
return {
eventInfo: {}
}
},
methods: {
timeFromNow(tmp) {
return moment(tmp).fromNow();
},
dayOfDate(d) {
let dt = moment(d, "YYYY-MM-DD");
return dt.format('dddd');
},
//event.id
getEventInfo(id){
let url = 'events/' + id;
axios.get(url)
.then((response) => this.handleResponse(response.data));
},
handleResponse(eventInfo) {
console.log(eventInfo);
// do something with the eventInfo...
}
}
Your axios call is asynchrone so your outside console.log will be process before the return of the response.
Just keep your code in the .then((response) => { // here i proceed the read more }

Resources