How to pass simple user input from Vue to Laravel Controller? - laravel

I'm trying to create something simple with Laravel + Vue.js without having to use the database.
I have two inputs from a Vue Component, and I was wondering how I pass those two values back into a Controller.
Usually, you use Axios to complete CRUD functions, but I honestly just want to pass simple values to the backend, and then have the backend transfer an array into back to the Vue Component.
Any advice? All the decent tutorials online usually use a database to transfer data back and forth.

Have you heard of inertiajs?
inertiajs allows you to create fully client-side rendered, single-page apps, without much of the complexity that comes with modern SPAs. It does this by leveraging existing server-side frameworks.

I was able to send data back and forth using axios
Here is what I had for my Vue Component:
<template> ... </template>
<script>
export default {
data() {
return {
name: '',
days: ''
}
},
methods: {
getData() {
axios.get('/api/urihere', {
params: {
name: this.name,
days: this.days
}
}).then((response) => {
console.log(response.data)
}).catch((error) => {
console.log(error)
})
}
},
mounted() {
//
}
}
</script>
While I had you had a simple get for Routes
Route::get('/urihere', [UrihereController::class, 'someMethod']);
and inside the said-controller
public function someMethod(Request $request)
{
return [$request->name, $request->days];
}

Related

Laravel vue.js 2 response view won't output parameters

I am new to vue.js and recently been assigned a project to learn it and refactor old code to vue.js like some of the existing pages already have been and I am having some issues. vue2
My question:
I have a get request with a controller that has a response something like this:
return Response::view('somebladefile', ['title' => 'some_title']);
Within the blade file I include a js file which will be responsible for vue
<script src="{{ cdnMix('somefile.js') }}"></script>
somefile.js contents:
const IndexPage = Vue.component('indexpage',require('./somepath/IndexPage.vue').default);
window.indexPageInstance = new IndexPage().$mount('#vuecontainerid');
So now within IndexPage.vue i would like to access variable 'title' that I passed with the response to my blade file originally. What would be the best way one would go about it? Tried few ways I found on YT/Google but without success, this is my code currently, any pointers would be appreciated, thanks!
<template>
<HeaderComponent></HeaderComponent>
</template>
<script>
const HeaderComponent = require('./somepath/HeaderComponent.vue').default;
export default {
name: 'indexpage',
props: ['data'],
components: {
'HeaderComponent': HeaderComponent,
},
data: function() {
return {
// why doesn't it work!!: '',
}
},
mounted: function() {
console.log(this.data);
}
}
</script>
Vue works, but I can't seem to be able to access 'title' variable.
Also I would like to be able to access 'title' within other components like the HeaderComponent I have within indexpage

How to check in a Vue component if a user is authenticated in Laravel?

As the title states, I'm a little confused how I would tackle a method in my Vue Component with if/else statement based on if the user is logged in and authenticated with Laravel's Auth facade. I'm making various Axios requests which I need to allow/disallow based on if user logged in.
I have VUEX setup and was thinking that I can use local storage somehow to have a state for isLoggedin for example that works with Laravel. But I don't know if this is correct method, or secure and presumably Laravel is already storing it's authentication. So can I just access that direct in Vue?
Some unclean solutions here that I don't think are the best -
https://laracasts.com/discuss/channels/vue/hide-button-if-user-is-logged-with-laravel-and-vuejs
I can not find any examples for this :(
Usually from your controller, you pass the authenticated user object into the view which will then be stored in a javascript variable
Controller:
public function index()
{
return view('index', [
'auth_user' => Auth::user()
]);
}
You will know if a user is authenticated if it returns an object or null where null means no user is authenticated.
In your blade, assign the auth_user into a javascript variable:
<script>
window.auth_user = {!! json_encode($auth_user); !!};
</script>
your vuex store object should atleast look like this:
{
state: {
user: null
},
mutations: {
setAuthUser(state, user) {
state.user = user;
}
},
getters: {
isLoggedIn(state) {
return state.user !== null;
}
}
}
Then in your Vue root component, get the auth_user and save it into the store:
<script>
export default {
mounted() {
this.$store.commit('setAuthUser', window.auth_user);
}
}
</script>
You now basically have a getter called this.$store.getters.isLoggedIn that you can use in your application for checking if a user is currently logged in.
e.g:
Use axios interceptors. You intercept the access denied http response code and then act accordingly.
window.axios.interceptors.response.use(function (response) {
return response;
}, function (error) {
if (419 === error.response.status) {
location.reload();
} else {
//Something else you want to do or do nothing
}
});
Putting a script within blade file will throw Vue Warning. Let me answer "How to check in a Vue component if a user is authenticated in Laravel" and leave you with your Vuex complexity. Also this method is simpler.
So, in your controller:
public function index()
{
return view('index')->with('auth_user', auth()->user());
}
In your blade(main.blade.php):
<div class="container">
<example-component :auth_user='#json($auth_user)'></example-component>
</div>
In your vue-component, get your props(ExampleComponent.vue):
<script>
export default {
props: ['auth_user'],
created () {
console.log(this.auth_user)
}
}
</script>
Returns null if user is not logged in
I'm working with laravel 7+
and it doesn't need to send Auth::user() via controller
Just call it from your laravel blade template file like below
your-template-name.blade.php
#if (Auth::check())
<script>window.authUser={!! json_encode(Auth::user()); !!};</script>
#else
<script>window.authUser=null;</script>
#endif
inside YourComponent.vue, store authUser like this:
<script>
export default {
data() {
return {
authUser: window.authUser
}
},
created() {
console.log(this.authUser);
},
methods: {
yourMethodName() {
console.log(this.authUser);
}
}
}
<script>

How to get a variable to bind from xhr call response in VueJS?

Ok I'm a beginner at VueJS and I'm just trying to do a simple XHR call and bind the json data response to my variable...
I have a component App.vue and this part of the template I want to show the results of the json. bpi is the name of the variable
<div id="simulationPoints">
<h2 className="logTitle">Full Log:</h2>
{{ bpi }}
</div>
then my script
export default {
name: 'App',
data: () => ({
bpi: []
}),
mounted: () => {
axios.get(`https://api.coindesk.com/v1/bpi/historical/close.jsonp?start=2011-01-01&end=2018-02-01`)
.then(response => {
this.bpi = response.data.bpi
})
.catch(e => {
this.errors.push(e)
})
}
}
This doesn't seem to work. I'm using Axiom to fetch the data and assign the response, and this is how all the examples I found online did it, but the array object I have is still empty and it doesn't render on the page. I don't know whats the issue here? A Vue expert please help :)
There are sorts of problem in your code.
First, don't use arrow function on options property or callback since arrow functions are bound to the parent context, this will not be the Vue instance as you’d expect.
Second, use return statement in your data function.
Third, use created hook for inserting data after instance is created. mounted hook is called for mutation after DOM is rendered.
export default {
name: 'App',
data: function() {
return {
bpi: []
}
},
created() {
axios.get(`https://api.coindesk.com/v1/bpi/historical/close.jsonp?start=2011-01-01&end=2018-02-01`)
.then(response => {
this.bpi = response.data.bpi
})
.catch(e => {
this.errors.push(e)
})
}
}

What is the best way to use Laravel route in Vue JS component

I have a vue js component which makes an axios request to a laravel route. But in the vue files I don't have access to the route() function and have to use static url's for now.
Here's some code:
web.php:
// API
Route::group(['prefix' => 'api'], function() {
// GET
Route::get('/brands', 'BrandsController#getBrands')->name('api-get-brands');
Route::get('/{brand_id}/models', 'BrandsController#getModels')->name('api-get-models');
Route::get('/fuel-types', 'BrandsController#getFuelTypes')->name('api-get-fuel-types');
Route::get('/gearboxes', 'BrandsController#getGearboxes')->name('api-get-gearboxes');
});
Vue component:
methods: {
getBrands: function() {
let app = this
axios.get('/api/brands')
.then(function(response) {
app.brands = response.data
})
.catch(function(error) {
console.log(error)
})
},
...
}
It works now but I wonder if that's the best way or is there some better way to do it
You can pass the route as props to the component inside the blade file.
Inside the view:
<component home-route="{{ route('home') }}"></component>
Inside the vue component:
<script>
export default {
props: ['homeRoute'],
}
</script>
Then you can access the route inside the component like so:
this.homeRoute
You can learn more about props here: https://v2.vuejs.org/v2/guide/components-props.html
Hope this helps.
The only way how to use routes with parameters that I found out is like this:
The route:
Route::get('route/{param1}/{param2}', [Controller::class, 'actionName'])->name('routeName');
The blade:
<component :route="'{{ route('routeName', ["", ""]) }}'"></component>
where the number of empty strings in the array is equal to the number of required parameters for the route.
The component:
<script>
export default {
props: {
route: String
},
data() {
return {
param1: "",
param2: ""
}
},
computed: {
fullRoute() {
return this.route + '/' + this.param1 + '/' + this.param2;
}
}
}
</script>
I am using Laravel 8 and Vue 3.
Use https://github.com/tighten/ziggy
Ziggy provides a JavaScript route() helper function that works like Laravel's, making it easy to use your Laravel named routes in JavaScript.
You can then use routes in JS just like in PHP
route('posts.index');
With parameters too
route('posts.show', [1]);

How can I preload data for vue.js in Laravel Spark?

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

Resources