vue component doesn't show data - laravel

Axios loads data without any problem, doesn't show any data, Laravel Mix builds without error.
I have following code:
index.html (body)
<div id="app">
<posts></posts>
</div>
In app.js I use this:
import Vue from 'vue';
// global declare axios
window.axios = require('axios');
import Posts from './components/Posts';
Vue.component('posts', Posts);
new Vue({
el: '#app',
props: {
posts:[{
userId: [Number],
id: [Number],
title: [String, Number]
}]
}
});
In the Posts.vue component I create a template and a script loading the data when mounted:
<template>
<ul>
<li v-for="post in posts" v-text="post.title"></li>
</ul>
</template>
<script>
export default {
data: function() {
return {
posts: null,
}
},
// when stuff is loaded (document ready)
mounted: function() {
// use placeholder data for tests, capture asynchronous data from site using this.
axios.get('https://jsonplaceholder.typicode.com/posts')
.then(response => this.posts = response.posts)
.catch(error => this.posts = [{title: 'No posts found.'}])
.finally(console.log('Posts loading complete'));
},
}
</script>
So the data should be shown as a ul list:
<ul>
<li>
title
</li>
<li>
title
</li>
<li>
title
</li>
</ul>

Try the code below, I've made comments on the bits that need changing.
data() {
return {
posts: [] // this should be an array not null
};
},
// you can do this on created instead of mounted
created() {
axios.get('https://jsonplaceholder.typicode.com/posts')
.then(response => {
this.posts = response.data; // add data to the response
});

` Here "this.post" not take it has instance in axios call.So you have follow like this. `
var vm=this;
axios.get('https://jsonplaceholder.typicode.com/posts')
.then(response => vm.posts = response.posts)
.catch(error => vm.posts = [{title: 'No posts found.'}])
.finally(console.log('Posts loading complete'));

Related

Laravel vue.js and vuex link body text by id and show in a new component

I am very new to Laravel and Vuex, I have a simple array of post on my page.
test 1
test 2
test 3
I am trying to link the text on the AppPost.vue component and show the post that has been clicked on a new component (AppShowpost.vue) on the same page. I believe I have to get the post by id and change the state? any help would be good. Thank you.
when you click test 1 it will show "test 1" on a new component (AppShowpost.vue)
In side my store timeline.js, I belive I need to get the post by id and change the state ?
import axios from 'axios'
export default {
namespaced: true,
state: {
posts: []
},
getters: {
posts (state) {
return state.posts
}
},
mutations: {
PUSH_POSTS (state, data) {
state.posts.push(...data)
}
},
actions: {
async getPosts ({ commit }) {
let response = await axios.get('timeline')
commit('PUSH_POSTS', response.data.data)
}
}
}
My AppTimeline.vue component
<template>
<div>
<app-post
v-for="post in posts"
:key="post.id"
:post="post"
/>
</div>
</template>
<script>
import { mapGetters, mapActions } from 'vuex'
export default {
computed: {
...mapGetters({
posts: 'timeline/posts'
})
},
methods: {
...mapActions({
getPosts: 'timeline/getPosts'
})
},
mounted () {
this.getPosts()
}
}
</script>
My AppPost.vue component. I need to link the post.body to display the post in my AppShowpost.vue component.
<template>
<div class="w-full inline-block p-4">
<div class="flex w-full">
<p>
{{ post.body }}
</p>
</div>
</div>
</template>
<script>
export default {
props: {
post: {
required: true,
type: Object
}
}
}
</script>
My AppSowpost.vue component that needs to display the post that is clicked.
<template>
<div>
// Displaypost ?
</div>
</template>
<script>
export default {
// Get post from id ?
}
</script>
Okay you can create a new state in your vuex "current_state", asyou said, you can dispatch a mutation by passing the id to the vuex.
state: {
posts: [],
current_state_id : null
},
In your mutations
set_state_id (state, data) {
state.current_state_id = data;
}
On your app post.vue, you can set a computed property that watches the current state
computed: {
currentState() {
return this.$store.getters["timeline/current_state_id"];
}}
And create a watcher for the computed property to display the current id/post
watch: {
currentState: function(val) {
console.log(val);
},
Maybe this will help you. First I will recommend to use router-link. Read about router link here if your interested. It is very helpful and easy to use. But you will have to define the url and pass parameter on our vue-route(see bellow).
1.You can wrap your post.body in router-link as follow.
//With this approach, you don't need any function in methods
<router-link :to="'/posts/show/' + post.id">
{{ post.body }}
</router-link>
2. In your AppSowpost.vue component, you can find the post in vuex state based on url params as follow.
<template>
<div> {{ thisPost.body }} </div>
</template>
// ****************
computed: {
...mapState({ posts: state=>state.posts }),
// Let's get our single post with the help of url parameter passed on our url
thisPost() { return this.posts.find(p => p.id == this.$route.params.id) || {}; }
},
mounted() { this.$store.dispatch("getPosts");}
3. Let's define our vue route.
path: "posts/show/:id",
name: "showpost",
params: true, // Make sure the params is set to true
component: () => import("#/Components/AppShowPost.vue"),
Your Mutations should look as simple as this.
mutations: {
PUSH_POSTS (state, data) {
state.posts = data;
}
},
Please let me know how it goes.

How can I update my VueJs Data function properties value while fetching data from API using axios?

I have successfully fetched data from API. The fetched data shows in the alert function. However, the properties in the data function such as - 'Recovered' is not updating. I can show the fetched data using Vanilla JS. But I want to update them automatically and want to show them like this {{Recovered}}.
How can I do it??
<template>
<div class="container">
<h2>Total Recovered: {{Recovered}}</h2>
</div>
</template>
<script>
import axios from 'axios'
export default {
name:'CoronaStatus',
data: function () {
return {
Recovered: '',
TotalConfirmed: '',
TotalDeaths: '',
// test: '30',
// test_2: 'maheeb',
// componentKey: 0,
}
},
mounted(){
this.globalStatus();
},
methods:{
globalStatus: function(){
// const self = this;
// this.componentKey += 1;
axios.get('https://api.covid19api.com/summary')
.then((response) => {
// this.recovered = response.data.Global.NewConfirmed;
this.Recovered= response.data.Global.TotalRecovered;
alert(this.Recovered);
// document.getElementById('test_5').innerHTML = "total: " + this.TotalRecovered;
}).catch(err=> console.log(err));
},
}
}
</script>
<style scoped>
</style>
The easiest solution would be to refetch the information every hour with setInterval.
The best solution would be to use the WebHook provided by covid19api.com.
Vue.config.devtools = false;
Vue.config.productionTip = false;
var app = new Vue({
el: '#app',
data: {
Recovered: "Loading ..."
},
mounted() {
setInterval(() => {
this.globalStatus();
}, 3600000); // Call globalStatus every hour
this.globalStatus();
},
methods: {
globalStatus: function() {
axios
.get("https://api.covid19api.com/summary")
.then(response => {
this.Recovered = response.data.Global.TotalRecovered;
})
.catch(err => console.log(err));
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
<div id="app">
<h2>Total Recovered: {{ Recovered }}</h2>
</div>

problem with vue-slick in laravel project

I facing a problem with using vue-slick carousel im my laravel project
I import it in main.js file import VueSlickCarousel from 'vue-slick-carousel'
Vue.use(VueSlickCarousel);
components: {
VueSlickCarousel
},
this is the component in my blade file
<VueSlickCarousel :arrows="true" :dots="true">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</VueSlickCarousel>
this is the error in the console
[Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.
please help me, Thanks in advance.
component code:
#push('scripts')
<script type="text/x-template" id="products-slider">
<div class="container" style="overflow:hidden;">
<div class="row">
<div class="col-12">
<h2 class="section-divider">
<span>
{{__('shop::app.home.new-products')}}
</span>
{{-- view all --}}
</h2>
<VueSlickCarousel :arrows="true" :dots="true">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</VueSlickCarousel>
{{-- <section class="regular slider">
#foreach (app('Webkul\Product\Repositories\ProductRepository')->getNewProducts() as $productFlat)
#include ('shop::products.list.old-card', ['product' => $productFlat])
#endforeach
</section> --}}
</div>
</div>
</div>
</script>
<script>
Vue.component('products-slider', {
import VueSlickCarousel from 'vue-slick-carousel',
template: '#products-slider',
components: {
VueSlickCarousel
},
data: function() {
return {
//products datat from API
products: [],
}
},
mounted: function () {
this.fetchProducts();
},
methods: {
// get products API
getProducts () {
return axios.get('{{url("/")}}/api/products?new=1&limit=6&order=desc&sort=created_at')
/* .then(response => {
const products = response.data.data;
this.products = products;
console.log(this.products);
}) */
/*try{
let prod = await axios.get('http://localhost/kshopnew/public/api/products');
const products = prod.data.data;
this.products = products;
}catch(e){
}*/
/*.then(response => {
this.products = response.data
})
.catch(e => {
this.errors.push(e)
})*/
},
// fetch products data
fetchProducts () {
this.getProducts ().then(response => {
const products = response.data.data;
this.products = products;
/* console.log(this.products); */
})
},
}
})
</script>
#endpush
Import vue-slick locally in your component and remove global registration
For example
<script>
import VueSlickCarousel from 'vue-slick-carousel'
export default {
components: {VueSlickCarousel}
}
</script>
In component code:
<script type="text/x-template" id="products-slider">
<div class="container" style="overflow:hidden;">
<div class="row">
<div class="col-12">
<h2 class="section-divider">
<span>
{{__('shop::app.home.new-products')}}
</span>
{{-- view all --}}
</h2>
<VueSlickCarousel :arrows="true" :dots="true">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</VueSlickCarousel>
{{-- <section class="regular slider">
#foreach (app('Webkul\Product\Repositories\ProductRepository')->getNewProducts() as $productFlat)
#include ('shop::products.list.old-card', ['product' => $productFlat])
#endforeach
</section> --}}
</div>
</div>
</div>
</script>
<script>
Vue.component('products-slider', {
template: '#products-slider',
data: function() {
return {
//products datat from API
products: [],
}
},
mounted: function () {
this.fetchProducts();
},
methods: {
// get products API
getProducts () {
return axios.get('{{url("/")}}/api/products?new=1&limit=6&order=desc&sort=created_at')
/* .then(response => {
const products = response.data.data;
this.products = products;
console.log(this.products);
}) */
/*try{
let prod = await axios.get('http://localhost/kshopnew/public/api/products');
const products = prod.data.data;
this.products = products;
}catch(e){
}*/
/*.then(response => {
this.products = response.data
})
.catch(e => {
this.errors.push(e)
})*/
},
// fetch products data
fetchProducts () {
this.getProducts ().then(response => {
const products = response.data.data;
this.products = products;
/* console.log(this.products); */
})
},
}
})
</script>
In main.js:
import VueSlickCarousel from 'vue-slick-carousel'
const app = new Vue({
el: '.element',
components: { VueSlickCarousel } // Note!!!
});
Remember to rebuild the front
my problem is fixed with :
Vue.component("VueSlickCarousel", require("vue-slick-carousel"));
instead of:
import VueSlickCarousel from 'vue-slick-carousel'
components: { VueSlickCarousel }

Trying to get a single data and display in a vue component, but nothing is displaying

I am using Laravel 5.8 + Vue.js in my project.
Trying to get a single data from a controller but nothing is displaying.
I added the 12345 in the component to check if the component is working, 12345 is showing well.
controller
public function getSingleData($idx)
{
$paymentData = PaymentData::where('idx', $idx)->first();
return view('paydetail')->with('paymentData', $paymentData);
}
router
Route::view('/paylist', 'paylist')->name('paylist.view');
Route::get('/paylist/data', 'PaymentController#getPaymentData')->name('paylist');
Route::get('/paydetail/{idx}', 'PaymentController#getSingleData')->name('paydetail');
blade
#extends('layouts.default')
#section('content')
<div class="container">
<paydetail :idx="{{ $paymentData->idx }}"></paydetail>
app.js
Vue.component('paydetail', require('./components/Paydetail.vue').default);
Paydetail.vue
<template>
<div>
<h2>12345</h2>
<div v-for="val in paymentData">
<h2>{{ val.app_name }} </h2>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
props: [ 'idx' ],
data() {
return {
paymentData: [{}],
}
},
created() {
this.paymentData = this.getPayDetailData();
console.log(this.idx);
console.log("here");
},
methods: {
getPayDetailData() {
axios({
method: 'GET',
url: '/paydetail/'+ this.idx
}).then(
response => {
console.log(response)
return response
},
error => {
console.log(error)
}
)
},
},
}
</script>
The result of console.log(response) is weird. It shows the whole html document which I don't understand at all.
It shows like this.
{data: "<!DOCTYPE html>↵<html>↵ <head>↵ <meta ch…>↵<!-- For Datatable -->↵↵↵ </body>↵</html>↵", status: 200, statusText: "OK", headers: {…}, config: {…}, …}
What did I wrong here?

Laravel router-link works only the first time

I am trying to fetch results from database in News.vue, and display them in Topnews.vue. I have two links fetched. When I click link1, it shows up the Topnews.vue template with everything working as intended, however, if i click link2, nothing happens, except for that the URL changes, but the template does not show up the result. If i refresh the page and click link2 or click on the navbar, then link2, it shows up, and same, clicking then link1, changes the URL, but doesnt show up. I'm really stuck on that and I'd be really glad if you help me out on that issue. Hope you understand.
News.vue
<template id="news">
<div class="col-sm-5">
<div class="cars" v-for="row in filteredNews" >
<div class="name" >
<p class="desc_top_time">{{row.created_at}}</p>
<span class="last_p"> {{row.category}}</span>
<h3 style="margin-bottom:-4px; font-size: 16px;">
<router-link class="btn btn-primary" v-bind:to="{name: 'Topnews', params: {id: row.id} }">{{row.title}}</router-link></h3>
</div></div></div>
</template>
<script>
export default {
data: function() {
return {
news: [],
}
},
created: function() {
let uri = '/news';
Axios.get(uri).then((response) => {
this.news = response.data;
});
},
computed: {
filteredNews: function() {
if (this.news.length) {
return this.news;
}
}
}
}
</script>
Topnews.vue
<template id="topnews1">
<div class="col-sm-7">
<div class="cars">
<img :src="topnews.thumb" class="img-responsive" width=100%/>
<div class="name" ><h3>{{ topnews.title }}</h3>
<p>
<br>{{ topnews.info }}<br/>
</p>
</div></div></div>
</template>
<script>
export default {
data:function(){
return {topnews: {title: '', thumb: '', info: ''}}
},
created:function() {
let uri = '/news/'+this.$route.params.id;
Axios.get(uri).then((response) => {
this.topnews = response.data;
});
}
}
</script>
Like GoogleMac said Vue will reuse the same component whenever possible. Since the route for both IDs use the same component Vue will not recreate it, so the created() method is only being called on the first page. You'll need to use the routers beforeRouteUpdate to capture the route change and update the data.
in TopNews.vue:
export default {
data:function(){
return {topnews: {title: '', thumb: '', info: ''}}
},
beforeRouteEnter:function(to, from, next) {
let uri = '/news/'+ to.params.id;
Axios.get(uri).then((response) => {
next(vm => {
vm.setData(response.data)
})
});
},
beforeRouteUpdate: function(to, from, next) {
let uri = '/news/'+ to.params.id;
Axios.get(uri).then((response) => {
this.setData(response.data);
next();
});
},
methods: {
setData(data) {
this.topnews = data
}
}
}
If you click a link referring to the page you are on, nothing will change. Vue Router is smart enough to not make any changes.
My guess is that the IDs are messed up. If you are using Vue devtools you will be able to easily see what data is in each link. Are they as you expect.

Resources