How to pass a Laravel filtered collection as array to Vue? - laravel

I have a component which I'm trying to make it receive an array.
If I do it like this in a blade file:
<mega-menu :grouped-categories="{{ $categories->toJson() }}"></mega-menu>
It works as intended. It appears in Vue as array.
However, if I try to run some collection methods like 'filter' and 'groupBy' and then apply 'toJson', Vue receives it as an Object which is not what I need.
<mega-menu
:grouped-categories="{{ $categories->filter(function($category) { return $category['enabled']; })->groupBy('group)->toJson() }}">
</mega-menu>
I'm suspicious that something is happening during filtering or grouping that converts it into an array. Any ideas on how to manipulate ´$categories´ variable which is an instance of Collection and make it pass as array to Vue?

According to the information provided by #Vivick, the associative arrays pass to Javascript as Objects. So I'll handle the Object inside the Vue component.

To avoid problems with special chars add addslashes in template like:
:users="'{{ addslashes(\App\Users::all()->toJson()) }}'"
In vue component get the Users as prop:
props: {
users: String
},
And add it to data
data() {
return {
users: JSON.parse(this.mailinglists)
};
},
Hope this helps.

use
v-bind:color="{{json_encode($yourVariable)}}"
in element
for example:
<color-item v-bind:color="{{json_encode($yourVariable)}}" ></color-item>
in your controller:
$myArray = array("name" => "لوازمات");
$item = "لوازمات";
$collection = Color::all();
return view('home', compact('item', 'collection', 'myArray', ...));
in your blade:
#extends('layouts.app', ['item' => $item,'myArray' => $myArray, 'colors'=> $collection])
pass variable into vuejs:
<primary-header
:colors="{{json_encode($colors)}}"
:item="{{json_encode($item)}}"
v-bind:my-array="{{json_encode($myArray)}}">
in your vuejs file
<template>
<div>
{{item}}
{{colors[0].name}}
{{myArray.name}}
</div>
</template>
<script>
export default {
name: "primary-header",
props: {
item: String,
myArray: Object,
colors: Array
},
methods: {
}
};
</script>
<style scoped>
</style>

Related

Laravel fetchi API Data + vue

Getting to know Laravel a bit more and I was wondering what's the best way to pass my data from my controller into my Vue component?
I have understood how to actually pass it as a prop, however, I can't seem to get it to render the way I want. my props in my Vue component are. My controller here:
{
public function fetch() {
$data = Http::get('https://jsonplaceholder.typicode.com/albums')->json();
return view('welcome', ['data' => $data]);
}
}
My view then passes on the data to my vue component like this.
<example-component :albums="#json($data)" />
My Vue props structure is below.
props: {
albums: {
type: Array,
default: []
},
}
Heres how im trying to render the data in my vue component:
<div>
<h1 v-for="album in albums" :key="album.id">
{{ album.title }}
</h1>
</div>
</template>
Results here enter link description here
I have verified the output from my controller is an array containing arrays. Am I handling the data wrong from the perspective of my Vue component?
you dont need to convert it to json :albums="#json($data)" it's already json ->json();
try replace
:albums="#json($data)"
with this
:albums="{{ $data }}"

how to access data ($count) from laravel controller to vue component

I want to access a variable $count from my controller and access it to a vue component (frontend). currently have this code on my controller:
public function index()
{
$count = User::where('created_at', Carbon::today())->count();
return view('user.index', compact('count'));
}
i am quite new to laravel and vuejs so please help me out. thank you!
Send count as a prop from blade to component
<your-component-name :count="{{ $count }}"></your-component-name>
And from your component, receive that prop
<template>
<div>
Count is {{ count }}
</div>
</template>
<script>
export default {
props: {
count: {
type: Number
}
}
}
</script>
To pass down data to your components you can use props. Find more info
about props over here. This is also a good source for defining those
props.
You can do something like:
<example :userId="{{ Auth::user()->id }}"></example>
OR
<example v-bind:userId="{{ Auth::user()->id }}"></example>
And then in your Example.vue file you have to define your prop. Then
you can access it by this.userId.
Like :
<script>
export default {
props: ['userId'],
mounted () {
// Do something useful with the data in the template
console.dir(this.userId)
}
}
</script>
the above question was answered in below question
Pass data from blade to vue component

What is the correct way to bring data from the controller to the vue.js? Laravel-vue.js

I haven't really used this method before and I'm confused where I'm going wrong.
I set the data in the controller, I added the mycourses entry but it's not coming through, everything else is coming in fine
$data['user'] = Auth::user()->load('userType');
$data['courses'] = StudentSchedule::where('instructor_id',Auth::user()->id)
->with('course', 'package.packageCourses', 'user', 'location')->get();
$data['mycourses'] = Course::all();
$data['locations'] = Location::all();
return view('home', $data);
After this I go to the blade and add this
<script>
const user = {!! json_encode($user) !!};
const mycourses = {!! json_encode($mycourses) !!};
const courses = {!! json_encode($courses) !!};
const locations = {!! json_encode($locations) !!};
</script>
Then this goes to the .js, but whats happening there is that its calling the vue
In the vue file I add this to the data()
courses: [],
mycourses: [],
locations: [],
In the vue file I add this to the mounted
this.courses = courses;
this.mycourses = mycourses;
this.locations = locations;
And the mycourses is giving me this error
Error in mounted hook: "ReferenceError: mycourses is not defined"
ReferenceError: mycourses is not defined
I added mycourses after all the other ones were added before, I have everything the same as the courses one and I'm still getting this error. What am I missing?
I'm not sure if this will be helpful or not, meaning perhaps there is a reason this method won't work given your circumstances.
I've found this method of setting/passing data to be pretty helpful. It's less overhead to have to parse in your blade templates (or wherever needed).
Controller
public function myFunction() {
...
$user = Auth::user()->load('userType');
$courses = StudentSchedule::where('instructor_id', $user->id)->with('course', 'package.packageCourses', 'user', 'location')->get();
$mycourses = Course::all();
$locations = Location::all();
// Verify the data is correct.
// dd($courses);
return view('example', compact('user', 'courses', 'mycourses', 'locations');
}
You can verify each is returning the value needed by checking what it's returning using dd().
If you have a vue component you are passing data to that exists in your blade template, you could do something like this to pass the data in as props
example.blade.php
<p>Example content...</p>
<p>Hello, {{ $user->name }}</p>
<example-component :courses="courses" :mycourses="mycourses"></example-component>
<p>...</p>
Now we have passed courses and mycourses to the view component. You can access them there:
<script>
export default {
name: 'ExampleComponet',
data() {
return {
//
}
},
methods: {
//
},
props: {
courses: {
type: Object,
required: true
},
mycourses: {
type: Object,
required: true
},
},
}
</script>
You'll need to update the property type for each of the props you pass in. Perhaps courses isn't an object, but rather a string.
I'm not sure if I've exactly solved your issue, but hope this helps get you in the right direction.

How to use Laravel helper functions with Vue?

Iam bulding a multi-page app using Laravel and Vue.Now, for example lets say I want to use some Laravel helper function like {{ trans('messages.welcome') }} inside a Vue component (which is in a separate .vue file) .. how to do that ?
Access the Laravel helper function from your Blade template, passing the result to your Vue component as a prop:
// app.blade.php
<message-component :message="{{ trans('messages.welcome') }}"></message-component>
// MessageComponent.vue
<template>
<div>{{ message }}</div>
</template>
<script>
export default {
props: [ 'message' ],
}
</script
In fact there is a way, kind of.
Inside data I called Laravel helper method with php tags. Code:
<script>
let app = new Vue({
el: '#app',
data: {
app_url: "<?php echo app_url(); ?>"
});
</script>
Here is another way to do what I believe #rook99
is trying to accomplish. This is working great for me.
Set up your Helper Functions in a a new folder in the app folder. I created a new folder in the app folder called CustomStuff. Then I set up a file called FormHelper.php . Add your Helper function to this file. This is the path to the Helper function file: app\CustomStuff\FormHelper.php
// This is my Helper Function. Create an array of states
public static function States()
{
$states =['AL', 'AK', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'DC', 'FL', 'GA',
'HI', 'ID', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'ME', 'MH', 'MD', 'MA', 'MI',
'MN', 'MS','MO', 'MT', 'NE', 'NV', 'NH', 'NJ', 'NM', 'NY', 'NC', 'ND', 'OH',
'OK', 'OR','PA', 'PR', 'RI', 'SC', 'SD', 'TN', 'TX', 'UT', 'VT', 'VA', 'WA',
'WV', 'WI', 'WY',];
return $states;
}
Set up a new controller. In the Controllers folder. Call it AppUtilityController Do not forget to add
use FormHelper;
at the top of the controller file. The following command in the command line will create the controller.
php artisan make:controller AppUtilityController
In the AppUtilityController add a function to be called from a root and return the Helper function data.
public function getHelperFunctions()
{
$data['states'] = FormHelper::States();
return $data;
}
set up a new route in your routes folder to call the getHelperFunctions
Route::get('/app-utilities/get-helper-functions',
'Admin\AppUtilityController#getHelperFunctions');
Next go to Vuejs component where you need the Helper Function.
Set up a function using created method so the function will get called when component loads.
Have the function make an api request to the url in the route. Which would be app-utilities/get-helper-functions. I am using axios to make the request.
The FormHelper functions will be returned as a javascript object. Simply use the object anywhere in the component.
In the future, whenever you want to add Helper function just add the new function to the FormHelper.php and AppUtilityController.php files and insert the method to grab the data in your Vuejs component.
I wrote a blog [post]: https://david.dukesnuz.com/blog/8/how-to-use-laravel-helper-functions-with-vuejs on this topic.
Just add script into blade template:
<script>
window.laravel_helper_result1 = '{{laravel_helper_function_1()}}';
window.laravel_helper_result2 = #json(laravel_helper_function_2());
</script>
Then you can use these js variables in your Vue.

How to pass javascript variable from laravel controller to vuejs component

I'm trying to build a page on Laravel 5.4 which contains few data which needs to be manipulated and then sent across the views. My view contains components of the vuejs v2.0. I want those data to be implemented in the components. I tried using the laracasts PHP Vars to JS transformer but unable to get it. I followed the steps by placing "laracasts/utilities": "~2.0" in my composer.json then I added the serviceprovider as mentioned in the documentation, I published the vendor and added the following in config/javascript.php,
'bind_js_vars_to_this_view' => 'Nitseditor.show',
I'm having a dynamic views folder which is currently inside my Nitseditor\home\resources\views Now in my controller I'm having following codes:
public function show()
{
JavaScript::put([
'foo' => 'bar',
'age' => 29
]);
return view(Nitseditor.show);
}
Now first of all it was throwing an error as I see that it was including use MongoDB\BSON\Javascript; then I removed and tried using use JavaScript
Now in the app.js file which is present in my asset folder, I'm including each components and trying to do console.log(foo); but its throwing an error foo not defined.
There are a few ways to do this depending on what you are trying to achieve and how your project is set up. The simplest way is to make a request to your controller from inside your component that returns json. Laravel 5.4 comes with axios so you can use that:
methods: {
getData(){
axios.get('/controller/route')
.then(response => {
// set your variables from the response
this.myData = response.data;
})
.catch(error => {
console.log(error);
});
},
data(){
return {
myData: {}
}
}
If you need child components to access the data then you would need to put that in the parent and pass myData" using props.
You could also create a directive and pass your variable down directly from your blade template:
Vue.directive('init', {
bind: function(el, binding, vnode) {
vnode.context[binding.arg] = binding.value;
}
});
Then you would just need to do:
<div v-init:vars="{foo: 'foo', age: 29}"></div>
And pass vars as props to any component that needs them:
Here's the JSFiddle: https://jsfiddle.net/3e05qwLh/
If you have multiple descendants that rely on your variables you will probably want to look at using vuex.
Dunno if it helps but I use this method for passing variables to javascript:
// in master layout (head section)
<meta name="foo" content="{{ $foo }}">
// in javascript (included or in the template)
foo = $('meta[name=foo]').attr('content');
If you have javascript in the blade template you can use directly this method:
foo = "{{ $foo }}";

Resources