Parse JSON encoded data in Vue Component - laravel

I am passing a json encoded data to my Vue component as a prop, when I am printing the whole prop variable then it is showing that the data has successfully received, but I am not able to parse the data.
profile.blade.php
#extends('layouts.app')
#section('content')
<my-profile user-details="{{ json_encode($userDetails) }}"></my-profile>
#endsection
MyProfile.vue
<template>
<div class="container">
<div class="row justify-content">
<div class="col-md-3" id="profile-image">
<img class="img-fluid rounded" src="https://www.w3schools.com/bootstrap4/paris.jpg" alt="Profile Image">
</div>
<div class="col-md-12">
<p>{{userDetails}}</p>
<p> Name: {{ userDetails.first_name }} </p>
</div>
</div>
</div>
</template>
<style>
#profile-image {
margin-bottom: 30px;
}
</style>
<script>
export default {
props: ["userDetails"]
}
</script>
Output
{"user_id":2,"first_name":"Shan","last_name":"Biswas","email":"shanpro.2015#gmail.com","phone":"9508168983","created_at":"2019-05-03 05:43:17","updated_at":"2019-05-03 05:43:17"}
Name:

You need to bind the value to the component as dynamic and not static.
So change your blade file to:
#extends('layouts.app')
#section('content')
<!-- see the colon in front of the props, that is a shortcut for v-bind:prop-name -->
<my-profile :user-details="{{ json_encode($userDetails) }}"></my-profile>
#endsection
Otherwise are all values passed to the component as a simple string.

Change this:
<my-profile user-details="{{ json_encode($userDetails) }}"></my-profile>
with this:
<my-profile user-details='#json($userDetails)'></my-profile>
// Pay attention to single quotes instead of double
This worked for me.

Update profile.blade.php to following!
#extends('layouts.app')
#section('content')
<my-profile user-details="{{ $userDetails }}"></my-profile>
#endsection

Related

Why can't I put <script> tags in my #section?

I have a #section('content') in a file home.blade.php which extends #extends('layouts.app'), for simplicity I'll use the generated Laravel scaffolding as an example.
home.blade.php:
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Dashboard</div>
<div class="card-body">
#if (session('status'))
<div class="alert alert-success" role="alert">
{{ session('status') }}
</div>
#endif
You are logged in!
</div>
</div>
</div>
</div>
</div>
#endsection
I try and add a script tag to the section:
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Dashboard</div>
<div class="card-body">
#if (session('status'))
<div class="alert alert-success" role="alert">
{{ session('status') }}
</div>
#endif
You are logged in!
</div>
</div>
</div>
</div>
</div>
<script src="js/example.js"></script> <!-- Adding my script here -->
#endsection
But then I get the following error in the console:
app.js:38355 [Vue warn]: Error compiling template:
Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as <script>, as they will not be parsed.
It says avoid placing script tags in templates? What exactly does this mean? How can I place a script within a #section, I don't want to put the script in my #extends('layouts.app'), I only want my script to work for this #section area.
You can use Blade stacks, they allow you to specifiy JavaScript for child views. In your home.blade.php add the following:
#push('scripts')
<script src="js/example.js"></script>
#endpush
This will push your script to a stack named scripts, you can name your stack to whatever you want. Then in your app.blade.php call the stack within your <head> tag as follows:
#stack('scripts')
Now your example.js file will only load for home.blade.php. Any other views that extend app.blade.php will not load this file.

Rendering HTML from database in vuejs component in laravel

I'm trying to fetch data from my database and display it as HTML content but it only turns out as a string, I'm using vuejs component in laravel. This is the code
<div id="main-window" v-for="post in posts">
<div class="post">
<div class="content">
{{post.content}}
</div>
</div>
How can I use the post.content as HTML?
You need to use v-html binding. Docs
<div id="main-window" v-for="post in posts">
<div class="post">
<div class="content" v-html="post.content">
</div>
</div>

How can I call view blade laravel in vue component?

My view blade laravel like this :
<section class="content">
<product-list :product-data="{{json_encode($products)}}"></product-list>
</section>
In the view blade call vue component
The vue compoponent like this :
<template>
<div class="box">
...
<div class="box-body">
<div class="box-footer">
<!-- call view blade -->
</div>
</div>
</div>
</template>
<script>
export default {
...
}
</script>
In the vue component, I want to call view blade laravel
The view blade like this :
{{$products->links()}}
I want to call it because the pagination only run in view blade
How can I do it?
You'd have to use a slotted component:
Vue Components:
<template>
<div class="box">
...
<div class="box-body">
<div class="box-footer">
<slot></slot>
</div>
</div>
</div>
</template>
<script>
export default {
...
}
</script>
Blade file
<section class="content">
<product-list :product-data="{{json_encode($products)}}">
{{$products->links()}}
</product-list>
</section>

Laravel Vue Component not being shown

I'm stucked with this code. I can't make it work, and i don't get any errors. Which might mean that i need an aditional dependency? It's simply not showing. Please help me. Thanks.
app.js - file
Vue.component('message', require('./components/Message.vue'));
const app = new Vue({
el: '#app'
});
Message.vue - file
<template>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Message</div>
<div class="panel-body">
I'm the component!
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
ready () {
console.log('Component ready')
}
}
</script>
home.blade.php - file
#extends('templates.default')
#section('content')
<h3>Welcome to Site</h3>
<div class="container">
<div id="app">
<message></message>
</div>
</div>
#stop
You may also need to clear browser cache when working with frontend. On mac this is command + shift + R. Also make sure you did run gulp to compile your js file.
Also make sure you included compiled js file to your layout template before </body>:
<script src="/js/app.js"></script>
I think you're missing the .default from the line
Vue.component('message', require('./components/Message.vue').default);

Laravel #section not showing

My issue is that when I define a section in a laravel blade (not master) I cannot display it's content on the page, however if I yield it on the master.blade.php it works fine. So how can I make this page display:
section 'content'
section 'template'
#extends('layouts.master')
#section('title', 'Website Builder')
#section('content')
<script type="text/javascript" src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script type="text/javascript" src="{!! asset('js/template.js') !!}"></script>
#endsection
#section('template')
<div class= "container template_class ">
#foreach ($templates as $template)
<a class="content-link" href="{{ asset($template->file )}}">
<img id = "image" src="{{ asset($template->image )}}"/>
</a>
#endforeach
</div>
<div id="content-link2"></div>
<div class="container">
#yield('content')
#yield('template')
</div>
#endsection
#show
So, if you already have a #section defined in the master layout, it will be overriden unless you specify #parent inside the child layout's #section.
But for #yield, it always gets the section from the child layout. That means it always overrides the #yield part, even if it has a default defined as #yield('section', 'Default Content')
Hope this works!

Resources