I am using laravel 6.0 and use vue components.After npm run dev I refresh the page and name(data on component) not showing. but after I refreshing page few times It will show up and some time again not showing the data (name) coming from request.
ExampleComponent.vue
<h5>{{name}}</h5>
data() {
return {
name: ''
}
},
mounted() {
axios.get('/api/user')
.then(response => {
console.log(response);
this.name = response.data.name;
});
},
Console log show the data and but sometime it not show in vue component. but some time works fine.In both time console log data shows correctly.
console log screenshot
I have already tried with
mounted() {
let self = this;
axios.get('/api/user')
.then(response => {
console.log(response);
self.name = response.data.name;
});
},
But nothing changed on situations.
It's better you can use created() instead of mounted(). created() fetch data when the component is created. Please have a look - click-here
Related
I searched the internet for a solution but none did work so far.
I am having a Vue component where I want to load dropdown content afterwards. Since it does not work, I simplified the code such that it should only show me the elements (which are driver names).
The problem is, that the v-for seems not to work, as the elements are not created in the DOM.
Here goes the code:
<template>
<div class="list-group">
<a class="list-group-item" v-for="driver in drivers">
{{driver.name}}
</a>
</div>
</template>
<script>
export default {
name: "DriverComponent",
data: function (){
return {
drivers: [],
}
},
mounted(){
this.loadDrivers();
console.log(this.drivers);
},
methods: {
loadDrivers: function(){
axios.get('/api/drivers')
.then(
(response) => {
this.drivers = response.data.data;
console.log(this.drivers);
}
)
.catch(function(error){
console.log(error);
});
// console.log(this.drivers);
}
}
}
</script>
In my app.js:
require('./bootstrap');
window.Vue = require('vue').default;
Vue.component('driver-component', require('./components/DriverComponent.vue').default);
const drivers = new Vue({
el: '#driv',
});
And my html looks as follows:
<div id="driv">
<driver-component></driver-component>
</div>
As you can see, I added some logs, which look like this:
Image of console output
Interestingly, it should be the same array, but the first array is empty but the second has the right values in it.-> EDIT: clarified, thank you
to highlight the problem: i would expect a list like:
v-for created list
Instead, I get a blank page.
It works, if I initialize the drivers array with the data I get in json. However, since I load the data afterwards, it seems not to work
Thank you for your help!
BR
Johannes
EDIT:
I am using "axios": "^0.21" and the controller is:
public function index(){
return DriverResource::collection(Drivers::all());
}
this controller returns the array in a data field, therefore, I set the response.data.data (meaning two times data)
The backend returns:
{"data":[{"id":1,"name":"UPS"},{"id":2,"name":"Hermes"}]}
See the homepage for axios. Under the "Response Schema" section they provide what a response looks like. Specifically for data, it's
{
// `data` is the response that was provided by the server
data: {}
< ... omitted for brevity ... >
}
Please check again what your backend is returning or is supposed to return. Log the whole response you get.
The this.drivers = response.data.data; seems to be incorrect, however the this.drivers = response.data; should work.
You didn't say which version of axios you are using or show your configuration so I'm using the following for an example:
axios = ^0.21.1
vue-axios = ^3.2.4
Replaced "name" with "title" to match the response format below:
{
"title": "delectus aut autem",
< ... omitted for brevity ... >
},
--
loadDrivers: function(){
Vue.axios.get('https://jsonplaceholder.typicode.com/todos')
.then(
(response) => {
this.drivers = response.data; // <<-- works and many task titles are shown on page
// this.drivers = response.data.data; // <<-- DOES NOT WORK LIKE FOR YOU, blank page
console.log(this.drivers);
}
)
.catch(function(error){
console.log(error);
});
// console.log(this.drivers);
}
I am trying to build an availability carousel. It will show the days of the week, and what time someone is available. I am using Laravel and vue.js. I have done the web api, and I can get the data object following the route
Route::group(['prefix' => '/{area}'], function () {
Route::get('/{tutor}/availability','Tutor\AvailabilityController#show');
});
with this in my availability controller
public function show(Request $request, Area $area, Tutor $tutor)
{
$availability = $tutor->availability()->get();
return response()->json([
'data' => $availability
], 200);
}
That all works.
But when I try and pull it into Vue, nothing shows up. I can't seem to figure out what I might be missing.
I pulled the vue component into blade using the following, and passing in the area and tutor id
<availability area-id="{{ $area->slug }}" tutor-id="{{ $tutor->slug }}">
</availability>
and in Availability.vue, I think where I am going wrong is pulling the data in with props, but I am really not sure anymore.
<script>
$(document).ready(function() {
$("#availability").owlCarousel();
});
export default {
props: {
areaId: null,
tutorId: null
},
data () {
return {
availability: []
}
},
methods: {
getAvailability () {
axios.get( '/' + this.areaId + '/' + this.tutorId + '/availability').then((response) => {
console.log(response.json());
});
}
},
ready () {
this.getAvailability();
}
}
</script>
Thank you for the help.
Axios response object has data field which contains the response from the server. To get the data use
response.data
Also for Vue 2.0 components use mounted instead of ready for when the component is ready. If you are only loading data from the server (and not manipulating the DOM) you can use created instead.
export default {
props: {
areaId: null,
tutorId: null
},
data () {
return {
availability: []
}
},
methods: {
getAvailability () {
var that = this;
axios.get( '/' + this.areaId + '/' + this.tutorId + '/availability')
.then((response) => {
console.log(response.data); // should print {data: availability_object}
// Set this component's availability to response's availability
that.availability = response.data.data;
//OR
//Add response's availability to the components' availability
that.availability.push(response.data.data);
});
}
},
mounted () {
this.getAvailability();
}
}
</script>
I am trying to build a carousel using Laravel 5.6 and Vue.js. I can call the data from db, and console.log response.data. It works like expect it to. Script below.
<script>
$(document).ready(function() {
$("#availability").owlCarousel();
});
export default {
props: {
areaId: null,
tutorId: null,
},
data () {
return {
availability: []
}
},
methods: {
getAvailability () {
var that = this;
axios.get( '/' + this.areaId + '/' + this.tutorId + '/availability').then((response) => {
console.log(response.data)
that.availability = response.data;
});
}
},
mounted () {
this.getAvailability();
}
}
</script>
Now I would expect to be able to display the data like
{{availability.monday_begin}}
but it displays nothing, empty tags.
When I add a second .data to response, so change
that.availability = response.data;
to
that.availability = response.data.data;
The data object shows up as undefined in the vue-dev tools, and {{ availability.monday_begin }} throws an error cannot read property of undefined.
I also tried adding a v-if to the template, based on a couple different articles I read, but nothing I tried worked.
Thanks for your help.
I have code like this:
app.js
require('./bootstrap');
window.Vue = require('vue');
Vue.component('qrcodes', require('./components/QrCodes.vue'));
const app = new Vue({
el: '#app'
});
Vue.config.devtools = true;
QrCodes.vue
<script>
export default {
data() {
return {
qrcodes:[],
qrcode: {
....
},
}
},
created() {
this.fetchQrCodes();
},
methods: {
fetchQrCodes() {
fetch('/api/qrcodes')
.then(res => res.json())
.then(res => {
console.log(res);
})
}
},
}
</script>
I assume everything should be fine but in the browser developer tools I am getting errors
app.js:47316 GET http://localhost/qrcodes 404 (Not Found)
fetchQrCodes # app.js:47316
created # app.js:47308
app.js:44443 You are running Vue in development mode.
Make sure to turn on production mode when deploying for production.
See more tips at https://vuejs.org/guide/deployment.html
app.js:47317 Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0
at app.js:47317
at
And those lines in browser developer tools looks like
methods: {
fetchQrCodes: function fetchQrCodes() {
var _this = this;
fetch('qrcodes').then(function (res) { // this line didnt change after building
return res.json(); // this line gives the second error
}).then(function (res) {
_this.qrcodes = res;
});
}
}
As you can see my fetchQrCodes() and browser does not match, fetching wrong url which I changed. I am running npm run watch tried turning it off and running npm run dev still browser code does not get updated. What could cause that?
EDIT: public/js/app.js is build correct and have the right changes but browser`s app.js does not.
According to the docs and examples, I have perfectly working code that functions great:
Vue.component('admin-competitions-index', {
data: function() {
return {
competitions: []
}
},
mounted() {
this.$http.get('/api/admin/competitions')
.then(response => {
this.competitions = response.data;
});
},
methods: {
/**
* Toggle whether a competition is published or not.
*/
togglePublished(competition) {
Spark.patch(`/api/admin/competitions/togglePublished/${competition.id}`, this.togglePublishedForm)
.then(response => {
competition.is_published = response;
});
}
}
});
However, I'd like to change this code to save the extra request that is made on page load. I don't see a convention anywhere in Laravel or Spark where this is done. I'm guessing that all I need to do is set a JS variable but I'm not sure where it would be proper to do so.
I also understand that this kind of defeats the point of using vue for asynchronous loading, but nevertheless I would like to learn this. I think it will become more useful if I were to use vue for my #show restful requests where even if I wanted everything to load asynchronously I would at the very least have to supply vue with the competition ID that I want loaded.
This works out of the box:
#section('scripts')
<script>
var competition = {!! $competition !!};
</script>
#endsection