Pass data into vuejs template - javascript

I have a Laravel application with vuejs2 support. Im using the router component in the vuejs part. How can I send data like sessions from laravel to a vuejs template. In my blade template I use <router-view ></router-view> to call the vue router component. How can I add data.
Thanks for help!

The page which you want to load using vuejs router component, add a script in the footer section of that page. And after using router push command, please refresh the whole page.
Keep a flag like: loading. At first, keep it true to view some initial message, and when you'll get axios response then make it false. Based on this flag, show the data that you get from axios response. And of course update the initially declared data after getting the axios response.
Example:
<script>
export default {
data(){
return {
loading:true,
// Others Data
}
},
methods:{
function_name (){
this.$router.push('/');
window.location.reload();
}
},
mounted() {
var _this = this;
axios.get('/data').then(function (response) {
//others data update
_this.loading=false;
});
}
}
</script>

You can use axios to make a get request to your laravel app.
Example method:
data() {
return {
data: ''
}
},
methods: {
getData: function () {
axios.get("/data")
.then((response) => {
this.data = response.data;
}, (error) => {
})
}
},
Note that you need to import axios in order to work:
import axios form 'axios'
Then you need to handle the request on the server side

Related

Nuxt asyncData not able to pull from authorized express routes

Building out an ecommerce store. Started with the products, which require no auth to pull, but do require auth to edit. This is working fine, and I suspect it's because this is happening on the client which sends auth info with all requests direct from client (ie methods hook).
However, order data does require auth to access any of it. I'm unable to access this route to generate the page using asyncData. I suspect this is because it's happening on the Nuxt server instead of on the client.
async asyncData({ $config: { apiURL } }) {
let orders = await axios.get(
`${apiURL}/orders`
);
return { orders: orders.data.data };
},
What is the correct way to do this? Set an empty data point then use mounted or created to pull and set?
Update: I got it working with as a method, but then you have to press the button to pull all the orders, that's pretty bad ux lol what do
An alternative solution would be
<template>
<section>
<div v-for="user in users" :key="user.id">
{{ user.name }}
</div>
</section>
</template>
<script>
export default {
async asyncData({ $axios, $config: { jsonPlaceholder } }) {
const fetchedUsers = await $axios.$get(`${jsonPlaceholder}/users`)
return { users: fetchedUsers }
},
data() {
return {
users: [],
}
},
}
</script>
This is using JSONplaceholder as an example, in your case you may add an additional data as you did initially.
This solution has the benefit of blocking the render of the page until the call is done (mounted() cannot).
Got it working, this is what I did:
data: () => ({
orders: []
}),
mounted() {
this.$axios.$get(`${this.$config.apiURL}/orders`).then( res => {
this.orders = res.data
})
},
Let me know if there's a better way to go

Vue prefetch data from separate backend

I have some queries from an API-Server that returns a json object that will be static over a user session, but not static forever.
It's a one-pager with Vue router.
How can I achieve that I:
can access this.myGlobals (or similar eg window.myGlobals) in all components, where my prefetched json-data from API-Server is stored.
My approach that is already working is to embed help.js via a mixin.
Oddly enough, I get hundreds of calls to this query. At first I thought that it only happened in the frontend and is chached, but the requests are actually sent hundreds of times to the server. I think it is a mistake of my thinking, or a systematic mistake.
i think the problem is, that the helper.js is not static living on the vue instance
main.js:
import helpers from './helpers'
Vue.mixin(helpers)
helpers.js:
export default {
data: function () {
return {
globals: {},
}
}, methods: {
//some global helper funktions
},
}, mounted() {
let url1 = window.datahost + "/myDataToStore"
this.$http.get(url1).then(response => {
console.log("call")
this.globals.myData = response.data
});
}
}
log in console:
call
SomeOtherStuff
(31) call
SomeOtherStuff
(2) call
....
log on server:
call
call
call (pew pew)
My next idea would be to learn vuex, but since its a easy problem, im not sure if i really need that bomb ?
You can use plugin to achieve this.
// my-plugin.js
export default {
install (Vue, options) {
// start fetching data right after install
let url1 = window.datahost + "/myDataToStore"
let myData
Vue.$http.get(url1).then(response => {
console.log("call")
myData = response.data
})
// inject via global mixin
Vue.mixin({
computed: {
myData () {
return myData
}
}
})
// or inject via instance property
Vue.prototype.$myData = myData
// or if you want to wait until myData is available
Vue.prototype.$myData = Vue.$http.get(url1)
.then(response => {
console.log("call")
myData = response.data
})
}
}
and use it:
Vue.use(VueResource)
Vue.use(myPlugin)

Vue v-if resolve Promise - implementing Laravel Gate in Vue

I'm trying to implement Laravel's authorization & policy in Vue, by implementing a mixin which sends a GET request to a controller in the backend.
The problem is the v-if directive is receiving a Promise, which obviously does not resolve
Below is a very simplified version of what I'm trying to do:
The global mixin, auth.js
import axios from "axios"
export default {
methods: {
async $can (permission, $model_id) {
let isAuthorized = false;
await axios.get(`/authorization?${permission}&${model_id}`)
.then(function (response) {
isAuthorized = response.data.isAuthorized
})
.catch((error) => {
isAuthorized = false;
});
return isAuthorized;
}
}
}
The main entry file, app.js
import Auth from '#/auth';
Vue.mixin(Auth);
...
new Vue({...})
Component.vue
<template>
<div>
<div v-if="$can('do-this', 12)">
Show Me
</div>
</div>
</template>
<script>
export default {}
</script>
Is there any way to 'await' the async $can operation in v-if? Or am I approaching this from a totally wrong direction?
You don't need async/await there because axios returns a promise. I think you can call that function from the created hook. Instead of returning a value, change the related data attribute, and use it in v-if like so:
<div v-if="permissions['do-this__12']">
data() {
return {
permissions: {
'do-this__12': false,
'or-this__13': false,
},
}
}
methods: {
getPermissions() {
for (const key in this.permissions) {
this.can(key.split('__')[0], key.split('__')[1])
}
},
can(permission, model_id) {
axios.get(`/authorization?${permission}&${model_id}`)
.then(response => {
this.permissions[`${permission}__${model_id}`] = response.data.isAuthorized
})
.catch(error => {
this.permissions[`${permission}__${model_id}`] = false;
});
},
}
created() {
this.getPermissions();
}
I didn't try my code, let me know if it fails. BTW, extracting this implementation to a mixin will be a better idea. If you like to do that, just leave "permissions" object in the component and move everything else to the mixin.
But that approach isn't effective when you need multiple API calls for permissions. That's why I think you should pass the whole permissions object to the backend and make the work in the server:
iPreferThisBecauseOfSingleAPICall() {
axios.get(`/authorization`, this.permissions)
.then(({ data }) => this.permissions = data)
}
// AuthorizationController
public function index(Request, $request)
{
$permissions = [];
foreach($request->all() as $permission) {
// run your backend code here
}
return $permissions;
}
One final note, instead of asking for permission each time, loading all permissions at one can be the best idea.

Chartjs + Vue.js - Cannot read property '_meta' of undefined

I am building an app using Vue.js + Chartjs. I am having a problem where I make a http call to a service to get data, parse it, and pass it into my Chartjs component. However, I keep getting the error Cannot read property '_meta' of undefined
Here are the relevant parts of my component:
<template>
<Chartjs :data="chartData" />
</template>
export default {
data () {
return {
chartData: false
}
},
created () {
this.getData()
},
methods: {
getData() {
const opts = {
url: 'some_url',
method: 'get'
}
request.callRoute(opts).then(results => {
this.chartData = results.data
}).catch(err => {
console.log(err)
})
}
},
components: {
Chartjs
}
}
Note - the chart renders fine if I hard code the chartData field with data that comes back from my request. However, it does NOT work if I make a http request first for my data.
Does anyone know what might be happening?
Thanks in advance!
Vue will render the component with the initial chartData (which is a boolean). You should use a v-if or other logic and render Chartjs component when you have the response. For example you can show a loading message/animation while the chartData is false.

How to get the latest data from parent to child components after page refresh

I am working on a project and using Vue.js for the frontend. I have following code in the main.js file.
new Vue({ // eslint-disable-line no-new
//el: '#app',
router,
data () {
return {
friends: []
}
},
methods: {
getFriends: function () {
return this.friends;
}
},
created: function () {
this.$http.get('/user/' + this.getUserIDCookie('userID') +
'/friends').then(function (response) {
this.friends = response.data;
});
},
components: {
'nav-bar': require('./components/Navigation.vue')
},
template: `
<div id="app">
<nav-bar></nav-bar>
<router-view class="router-view"></router-view>
</div>`
}).$mount('#app');
In one of the pages(for ex. when the page is redirected to localhost/#/user/1/details, I am retrieving the friends' list from main.js like below:
<script type="text/babel">
export default {
name: 'profile',
data: function () {
return {
user: {},
friends: []
}
},
methods: {
// Some methods
},
created: function () {
this.friends = this.$root.getFriends();
}
}
</script>
The problem arises when I refresh the current page. After page refresh, this.friends is null/undefined because this.$root.getFriends() is returning null/undefined. I can move it to user component, but I want to keep it in main.js so that GET call is used once and data will be available to the whole application.
Any input regarding how to solve this issue would be great. I am using Vue 2.0.1
Really, what you want to do, is pass the data the component needs as props.
The dirt simple easiest way to do it is this.
<router-view class="router-view" :friends="friends"></router-view>
And in your profile component,
export default {
props:["friends"],
name: 'profile',
data: function () {
return {
user: {},
friends: []
}
},
methods: {
// Some methods
}
}
If you want to get more sophisticated, the later versions of VueRouter allow you to pass properties to routes in several ways.
Finally, there's always Vuex or some other state management tool if your application gets complex enough.
The problem is that when you refresh the page, the whole app reloads, which includes the get, which is asynchronous. The router figures out that it needs to render details, so that component loads, and calls getFriends, but the asynchronous get hasn't finished.
You could work around this by saving and pulling the Promise from the get, but Bert's answer is correct: the Vue Way is to send data as props, not to have children pull it from parents.

Categories