Checkout the new cookbook section on the spark documentation. It covers exactly this case.
Spark: How VueJS insert data into input ?
Hello,
I created a new form inside settings in spark. That form is for "user_data" table, it's an extension with more rows for "user" table. I was able to insert data in that table, but i don't know how to show that informations inside form inputs, via VueJS?
In a perfect world i think it will be like this:
ready() { this.form.first_name = this.user_data.first_name; }
but i don't know how to initialize that "this.user_data"
Can someone give me some ideas ?
before to ask here i made some research, i sow that tutorials, but my question is: How i can grab data from that db table "user_data" via vuejs (similar with "user" table)
in vuejs i can access that details from that "user" table with : this.user.name or this.user.id, how to do the same with "user_data"
Simple Solution
By default there is what is called the "Global spark object" this is located in resources/views/layouts/app.blade.php like so:
<!-- Global Spark Object -->
<script>
window.Spark = <?php echo json_encode(array_merge(
Spark::scriptVariables(), []
)); ?>
</script>
Add a new array of data into the code there for example:
<!-- Global Spark Object -->
<script>
window.Spark = <?php echo json_encode(array_merge(
Spark::scriptVariables(), $myNewArrayOfValues
)); ?>
</script>
Or
<!-- Global Spark Object -->
<script>
window.Spark = <?php echo json_encode(array_merge(
Spark::scriptVariables(), ['key' => 'value', 'foo' => 'bar']
)); ?>
</script>
My Solution
If however you want slightly nicer solution which allows for data to only be loaded on certain views instead of all views I came up with the following:
Replace the above global spark object code with the following:
<!-- Global Spark Object -->
<script>
window.Spark = {!! json_encode(Spark::scriptVariables()) !!}
@stack('global-spark-objects')
</script>
and in src/Configuration/ProvidesScriptVariables.php add the following:
'injectedObjects' => [],
From there you can inject from any view the following:
@push('global-spark-objects')
window.Spark.injectedObjects.newObject = {!! json_encode(['newObject']) !!};
@endpush
its not the most elegant, I'm not a fan of the global spark object, and I'm quite certain Taylor is working on something to make it nicer, but hopefully that helps :)
I've done a similar thing recently but with a ViewComposer and shared view variables, so that you can just define the data on your view like this:
// assign some values to the template variable $vue_inject
return view('sites')->with('vue_inject', [
'foo' => $foo,
'bar' => $bar
]);
And you can then access the injected variables in vue as spark.injectedData.foo and spark.injectedData.bar. Obviously it would be nicer to extend the View and add a new method for this, instead of using a variable with hard-coded name, but I was in a bit of hurry with the project.
For this to work just create a new ViewComposer (I've added it to a new folder app/Http/ViewComposers).
namespace App\Http\ViewComposers;
use Illuminate\View\View;
class VueDataComposer
{
/**
* Take a local variable $vue_inject from the current view (if set) and
* share it with all views, so that it can be added to the global Spark object
*
* @param View $view
* @return void
*/
public function compose(View $view)
{
$view_factory = $view->getFactory();
$view_data = $view->getData(); // local view variables
// if the special variable is set on the view
if (isset($view_data['vue_inject'])) {
// get the data for vue
$inject_var = $view_data['vue_inject'];
// get all data injected by other views
$vue_shared = $view_factory->shared('vue_injected_data', []);
// merge & re-share
$view_factory->share('vue_injected_data', array_merge($vue_shared, $inject_var));
}
}
}
Also add this line to SparkServiceProvider::booted() method to register the view composer to run on every view:
view()->composer('*', 'App\Http\ViewComposers\VueDataComposer');
And then update the layout template, so that we inject variables into the Spark object
<!-- Global Spark Object -->
<script>
window.Spark = <?php echo json_encode(array_merge(
Spark::scriptVariables(), [
'injectedData' => isset($vue_injected_data) ? $vue_injected_data : [],
]
)); ?>
</script>
Now you can access the assigned variables in your vuejs templates as spark.injectedData.foo, while keeping the blade templates clean.
Please or to participate in this conversation.