Laravel: How do I parse this json data in view blade? - json

Currently this is my view
{{ $leads }}
And this is the output
{"error":false,"member":[{"id":"1","firstName":"first","lastName":"last","phoneNumber":"0987654321","email":"email#yahoo.com","owner":{
"id":"10","firstName":"first","lastName":"last"}}]}
I wanted to display something like this
Member ID: 1
Firstname: First
Lastname: Last
Phone: 0987654321
Owner ID: 10
Firstname: First
Lastname: Last

It's pretty easy.
First of all send to the view decoded variable (see Laravel Views):
view('your-view')->with('leads', json_decode($leads, true));
Then just use common blade constructions (see Laravel Templating):
#foreach($leads['member'] as $member)
Member ID: {{ $member['id'] }}
Firstname: {{ $member['firstName'] }}
Lastname: {{ $member['lastName'] }}
Phone: {{ $member['phoneNumber'] }}
Owner ID: {{ $member['owner']['id'] }}
Firstname: {{ $member['owner']['firstName'] }}
Lastname: {{ $member['owner']['lastName'] }}
#endforeach

it seems you can use #json($leads) since laravel 5.5
https://laravel.com/docs/5.5/blade

For such case, you can do like this
#foreach (json_decode($leads->member) as $member)
{{ $genre }}
#endforeach

You can use json decode then you get php array,and use that value as your own way
<?php
$leads = json_decode($leads, true);
dd($leads);

The catch all for me is taking an object, encoding it, and then passing the string into a javascript script tag. To do this you have to do some replacements.
First replace every \ with a double slash \\ and then every quote" with a \".
$payload = json_encode($payload);
$payload = preg_replace("_\\\_", "\\\\\\", $payload);
$payload = preg_replace("/\"/", "\\\"", $payload);
return View::make('pages.javascript')
->with('payload', $payload)
Then in the blade template
#if(isset($payload))
<script>
window.__payload = JSON.parse("{!!$payload!!}");
</script>
#endif
This basically allows you to take an object on the php side, and then have an object on the javascript side.

in controller just convert json data to object using json_decode php function like this
$member = json_decode($json_string);
and pass to view in view
return view('page',compact('$member'))
in view blade
Member ID: {{$member->member[0]->id}}
Firstname: {{$member->member[0]->firstname}}
Lastname: {{$member->member[0]->lastname}}
Phone: {{$member->member[0]->phone}}
Owner ID: {{$member->owner[0]->id}}
Firstname: {{$member->owner[0]->firstname}}
Lastname: {{$member->owner[0]->lastname}}

Example if you have array format like this:
$member = [
[ "firs_name" => "Monica",
"last_name" => "Dev",
"sex" => "F"
],
[ "firs_name" => "Blake",
"last_name" => "Devante",
"sex" => "M"
],
[ "firs_name" => "Johnny",
"last_name" => "Merritt",
"sex" => "M"
]
]
You can use #json Blade directive for Laravel 5.5 to 9.x
<script>
var app = #json($member);
</script>
From Laravel 8.x to latest version you can use Illuminate\Support\Js::from method directive.
<script>
var app = {{ Illuminate\Support\Js::from($member) }};
</script>
And for short with Js facade
<script>
var app = {{ Js::from($array) }};
</script>
Reference:
https://laravel.com/docs/blade

If your data is coming from a model you can do:
App\Http\Controller\SomeController
public function index(MyModel $model)
{
return view('index', [
'data' => $model->all()->toJson(),
]);
}
index.blade.php
#push('footer-scripts')
<script>
(function(global){
var data = {!! $data !!};
console.log(data);
// [{..}]
})(window);
</script>
#endpush

Just Remove $ in to compact method ,
return view('page',compact('member'))

Related

Quasar Q-Table and Data from Array (IndexedDB & Dexie)

I am new to Quasar and Javascript and I'm trying to get data from my database (IndexedDB using Dexie) into my q-table.
I have the skeleton of the q-table and I'm getting the data from Dexie, in the form of an Array, but I don't know how to display the data in the table and I would love some help.
I've read about maybe having to use computed, and/or the map option but I don't know enough about either of those to use them. I've been googling and reading the Quasar docs and I'm still not sure what to do. I don't know if I can put it in a codepen since it's getting data from a database.
I have this live online at https://entrypaws.com/ you may have to hit shift-reload to get the latest version as my host has an online cache it keeps, though I've cleared it. This small table section is reachable by clicking the 'view test table' link in the left sidebar.
Here is my html:
<q-page>
wholething: {{ this.thePersonArray }} // this displays correc
<br/><br/>
hmmm: {{ this.thePersonArray[0].f_lastName }}
<q-table
title="Treats"
:rows="rows"
:columns="columns"
row-key="name"
binary-state-sort
>
<template v-slot:body="props">
<q-tr :props="props">
<q-td key="name" :props="props">
{{ props.row.name }}
</q-td>
<q-td key="lname" :props="props">
{{ props.row.lname }}
</q-td>
<q-td key="dogbreed" :props="props">
<div class="text-pre-wrap">{{ props.row.dogbreed }}</div>
</q-td>
<q-td key="phone" :props="props">
{{ props.row.phone }}
</q-td>
</q-tr>
</template>
</q-table>
</q-page>
</template>
and this is my script:
import { ref } from "vue"
import theDB from "../components/dexiedb.js"
const columns = [
{
name: 'name',
label: 'First Name',
field: row => row.name, // f_lastname:
},
{ name: 'lname', label: 'Last Name', field: 'lname'},
{ name: 'dogbreed', label: 'Dog Breed', field: 'dogbreed'},
{ name: 'phone', label: 'Phone', field: 'phone'},
]
const rows = [
{
name: 'Susan',
lname: 'Smith',
dogbreed: 'Danish-Swedish Farmdog',
phone: '801.810.9990',
},
{
name: 'James',
lname: 'Jones',
dogbreed: 'Kromfohrlander',
phone: '801.930.9999',
},
]
export default {
name: "testtable",
setup() {
return {
columns,
rows
}
}, // end setup
data() {
return {
thePersonArray: [],
}
}, // end data
created() {
this.getTheUsers()
}, // end mounted
methods: {
getTheUsers() {
this.thePersonArray = []
console.log(" getTheUsers 1 ", this.thePersonArray)
this.thePersonArray.push({f_lastName: "Dreamer"}) // if the array is not initialized i seem toget an error
theDB.personTable
.orderBy('f_lastName')
.each((personOBJ) => {
this.thePersonArray.push(personOBJ)
console.log(" inside: ", this.thePersonArray)
}).then(() => {
// Transaction committed.
console.log(" People: Transaction committed")
}).catch(err => {
// Transaction aborted.
console.log(" People: Transaction aborted")
})
console.log(" after done: ", this.thePersonArray)
}
}, // end methods
} // end export
</script>```
I'd love some help. I'm completely stuck.
[1]: https://entrypaws.com/
Try making thePersonArray reactive by using ref
data() {
return {
thePersonArray: ref([]),
}
},
then assign the new array to thePersonArray.value
getTheUsers() {
this.thePersonArray.value = []
I think you might be able to push directly with thePersonArray as I think Vue maps/ wraps/ proxies these methods (whatever they call it :) ), so try
this.thePersonArray.push({f_lastName: "Dreamer"})
and if that doesnt work try
this.thePersonArray.value.push({f_lastName: "Dreamer"})
but I think the first will work

Nunjucks nested variables

Are nested variables possible in Nunjucks? I need to be able to store a string in my database containing Nunjucks variable but it does not seem to work. Here's an example of what I need to be able to do:
dict = {
name: 'John',
lastname: 'Smith',
greeting: 'Hello, my name is {{ name }} {{ lastname }}'
}
And then be able to do
<span>{{greeting}}</span>
but it outputs this:
'Hello, my name is {{ name }} {{ lastname }}'
The reason i need it this way it because I have a database with some description templates with holes and i have a database with values and I need to be able to combine them. But it is not always the same values so I cant hard-code them.
The simplest way is a add global or filter
var nunjucks = require('nunjucks');
var env = nunjucks.configure();
env.addFilter('render', function(text) {
return nunjucks.renderString(text, this.ctx);
});
var res = nunjucks.renderString(
'name: {{name}}, greeting: {{greeting | render}}',
{
name: 'John',
greeting: 'Hello {{name}}'
}
);
console.log(res);

How to work with JSON coming from api-platform

I've installed the api-platform demo on a server and I did a client app (working with Symfony 3.3) and I want to display the response in a classic view (Twig).
Everything's working fine : I can request and retrieve the response.
But here's where i'm stuck : when I dump the response in my view I got this
{"#context":"\/contexts\/Book","#id":"\/books","#type":"hydra:Collection","hydra:member":[{"#id":"\/books\/1","#type":"Book","id":1,"isbn":"9783161484100","title":"1st Book","description":"This is my first book synopsis","author":"Hemingroad","publicationDate":"2018-02-16T14:15:58+00:00","reviews":[]}],"hydra:totalItems":1}
Here's my controller's method :
//...
use GuzzleHttp\Client;
public function newAction(Request $request)
{
//initialize client API
$client = new Client([
'base_uri' => 'http://my.apidomain.com/',
'timeout' => 2.0,
]);
//request to API
$dataBooks = $client->request('GET', 'books', ['auth' => ['login', 'p#$$w0rd']]);
$listBooks = $dataBooks->getBody()->getContents();
return $this->render('book/new.html.twig', array(
'listBooks' => $listBooks
));
}
I've also tried to json_decode and using JMSSerializer on $listBooks.
I got a beautiful object but I still cant access the JSON attribute's like ISBN, title by doing something like
{% for book in listBooks %}
{{ dump(book.title) }}
<!-- .... -->
{% endfor %}
Here's what I got when I json_decode $listBooks :
{{ dump(listBooks) }}
I got an error when I try to access every field like this
{{ dump(listBooks.#id) }}
{{ dump(listBooks['hydra:member']) }}
....
Am I missing something ?
Thanks
$dataBooks->getBody()->getContents(); returns a string, as described in Guzzle's documentation, so you need to use json_decode.
$listBooks = json_decode($listBooks); returns an object. In Twig you can use the dot notation to access methods and properties of an object, e.g. {{ listBooks.myProp }}. But because hydra:member includes a special character (:), you need to use Twig's attribute function, as described in Twig's documentation:
{{ attribute(listBooks, 'hydra:member') }}
Another approach is to do $listBooks = json_decode($listBooks, true); so that you get an associative array instead of an object. Then you can use the bracket notation in Twig:
{{ listBooks['hydra:member'] }}
I would prefer this second approach, because in my opinion {{ listBooks['hydra:member'] }} is much clearer and cleaner than {{ attribute(listBooks, 'hydra:member') }}.

How to populate dropdown from database laravel 5.x

Controller side:
$regs = Model::all('id','name');
return view('aview',compact('regs'));
View side:
{{ Form::select('id', $regs) }}
The dropdown gets rendered and populated but displays JSON objects such as {"id:1","name: Aname"} instead of displaying Aname and setting the post value to 1
Try this
In your controller
$regs = Model::pluck('name','id');
Keep your view same
Hope this will work
You can populate like this:
{!! Form::select('id', $regs->lists('name', 'id'), null, ['class' => 'form-control']) !!}
Form::select accepts four parameters:
public function select($name, $list = [], $selected = null, $options = []);
The name of the html field
the list of options
the selected value
an array of html attributes
You can generate the list by using
$regs = Model::all('id','name');
$plucked = $regs->pluck('name', 'id');
// $plcuked = ['id1' => 'name1', 'id2' => 'name2' ...]
And the blade code should look like this
{{ Form::select('name', $plucked, null, ['class' => 'form-control']); }}
I maybe making this problem a bit complicated but I think its worth using the plugin.
You can take the use of very popular plugin - Select2. This plugin of jQuery helps you to fetch data from server and populate the fetched data into our dropdown in minutes. Your code goes like this.
// Code in your Controller Method
$regs = Model::all();
$data = [];
foreach($regs as $reg) {
$data[] = [
'id' => $reg->id,
'text' => $reg->name
];
}
return json_encode(['items' => $data]);
// Code in your desired View
<select id="select_items"></select>
// Code in js
$('#select_items').select2({
ajax: {
url: '/example/api', // <--------- Route to your controller method
processResults: function (data) {
return {
results: data.items
};
}
}
});
You can also integrate search options using this plugins as it helps you to fetch results based on your search keywords (for more see Select2 Examples). Hope this helps you to solve your problem.

How to render values of an array containing strings or any other basic type using JsRender

Using JsRender, I'm trying to render out the values of an array full of strings, and they're coming out as blank. I've tried {{:$value}}, {{:$data}}, {{:value}} and {{:data}} and none of them work. What is the syntax to do this?
Template:
<script id="tmpl" type="text/x-jsrender">
{{:author}} wrote these books:<br/>
{{for books}}
book=<span>{{:$data}}{{:$value}}{{:data}}{{:value}}</span>
{{/for}}
<br/><br/>
</script>
JS:
var data = [
{ author: "John", books: [ "j1","j2","j3" ]},
{ author: "Sarah", books: [ "s1","s2","s3" ]}
];
var tmpl = $.templates("#tmpl");
var html = tmpl.render(data);
$("div").html(html);
It's rendering...
John wrote these books:
book= book= book=
Sarah wrote these books:
book= book= book=
Live example here: http://jsbin.com/kutude/1/edit?html,js
You're right, you can write:
{{for books}}<span>{{:#data}}</span>{{/for}}
But alternatively you can simply write:
{{for books}}<span>{{:}}</span>{{/for}}
Since {{:xxx}} defaults to the current data item, so you can access it either with no parameter, or with the parameter #data
It's {{:#data}} ! Update: {{for books}}<span>{{:#data}}</span>{{/for}}