I'm working with Symfony 3, Angular JS and Twig. My problem comes when I try to generate a JSON in a view(html.twig).
My Model (MongoDB)
{
"_id" : ObjectId("5a1feb783e06fa060c0076b2"),
"contenido" : [
[
{
"type": "item",
"name": "Foo",
"id": 5
},
{
"type": "item",
"name": "Bar",
"id": 6
}
]
]
}
My Controller:
class Controlador extends Controller
{
// This method retrieve data (Document) from MongoDB
public function renderizar(Request $request)
{
...
$repository= $this->get('doctrine_mongodb')
->getManager()
->getRepository('AppBundle:Class');
$object = $repository->find('5a1feb783e06dfa060c0076b2');
$contenido = json_encode($object->getContenido());
$contenidoB = htmlentities($contenido);
$contenidoC = html_entity_decode($contenidoB);
$contenidoDef = json_decode($contenidoC);
return $this->render('view.html.twig', 'contenido' => $contenidoDef));
}
}
I want to generate that JSON in the view (inside the AngularJS's controller) in order to render a drag and drop panel from AngularJS.
My view
{% block body %}
<!doctype html>
<html >
<head>
<script>
angular.module("app").controller("NestedListsDemoController", function($scope)
{
$scope.models = {
dropzones: {
"A": [
{
"type": "container",
"name": "container",
"id": 4,
"columns": [
[
{
"type": "item",
"name": "Foo",
"id": 5
},
{
"type": "item",
"name": "Bar",
"id": 6
}
]
]
}
]
}
};
});
</script>
...
{% endblock %}
The Angular's controller doenst recognize the JSON in view if I use variable that contains that JSON.
dropzones: {
...
"A": {{ contenido|raw }}
}
or
dropzones: {
...
"A": {{ contenido }}
}
However, If I write the JSON in the view, it works. But I need to put the content from that variable. Any idea? Could anyone help me?
I solved the problem changing the string I would received in controller. When I retreive the document from MongoDB (I don't know why) comes with an extra double [ ] . Then, the drag and drop panel didn't recognize that JSON format...
To solve, first I removed them in controller, secondly I generated the JSON in the view as follows:
dropzones: {
"A": [ {{ contenido|raw }} ]
}
That's all, it works for me.
Use this:
dropzones = {{ contenido|json_encode|raw }};
Related
I have JSON that looks like this:
[
{
"Data": {
"BagData": null,
"OtherData": {
"Responses": [
"test"
]
}
}
},
{
"Data": {
"BagData": {
"BagWeight": 20.0,
"ExceededBy": 0.0
},
"OtherData": null
}
}
]
I'm trying to transform this using a Liquid template. I want to simply output the JSON object literal for "Data" unchanged, but using a different property name so that the output is:
[
{
"MessageDetails": {
"BagData": null,
"OtherData": {
"Responses": [
"test"
]
}
}
},
{
"MessageDetails": {
"BagData": {
"BagWeight": 20.0,
"ExceededBy": 0.0
},
"OtherData": null
}
}
]
I'm using the following Liquid transform template, however it's outputting nothing in place of transaction.Data (content definitely contains the correct array of JSON object literals)
[
{% for transaction in content %}
{
"MessageDetails": {{ transaction.Data }},
},
{% endfor %}
]
How do I output the value of "Data" unchanged? I want it to work even if the structure for the value of "Data" changes. So, if the value of "Data" is:
{
"SomethingCompletelyDifferent": null
}
I still want that to appear in the output, so that the final output would be:
[
{
"MessageDetails" : {
"SomethingCompletelyDifferent": null
}
},
...
]
Have you tried breaking the JSON down further so it is more specific?
{% for transaction in content %}
{
"MessageDetails": {
"BagData": {
"BagWeight": {{transaction.MessageDetails.BagData.BagWeight}},
"ExceededBy": {{transaction.MessageDetails.BagData.ExceededBy}}
},
"OtherData": {{transaction.MessageDetails.OtherData}}
}
},
{% endfor %}
When writing out the template I find that you need to be specific on how you want it to look. Writing out each key and then calling its value allows you to template the JSON exactly how you want it too.
The for loop maps through each object it has received and will create what you have templated per object.
I have imported the following json file:
[
{
"case_id": "1234",
"thread": [
{
"t_id": "1111",
"text": "test"
},
{
"t_id": "2222",
"text": "test"
}
]
},
{
"case_id": "5678",
"thread": [
{
"t_id": "9999",
"text": "test"
},
{
"t_id": "8888",
"text": "test"
},
{
"t_id": "777",
"text": "test"
}
]
}
]
using the following:
import cases from '../cases.json'
The whole json dataset is available in cases variable and can be used in the template with the support of v-if and v-for.
How can I create a separate dataset (thecase) that contains only threads for a given case_id? In the template I would only like to use v-for to display all threads for a given case_id.
Below is my export default section:
export default {
name: "details",
props: {
case_id: {
required: true,
type: String
}
},
data () {
return {
cases,
thecase: ### THIS IS THE PART I CANNOT FIGURE OUT ###
}
}
};
You can remove thecase from data options and use a computed property instead for thecase. Inside the computed property, we will need to use array .find() method to find the case where case_id is same as the case_id passed in the prop:
data: {
cases,
},
computed: {
thecase: function() {
return this.cases.find(c => c.case_id === (this.case_id || ''))
}
}
and then you can use v-for on thecase.thread just like you would do for a data option like:
<li v-for="item in thecase.thread" :key="item.t_id">
{{ item.text }}
</li>
You can further modify it and use v-if & v-else to show a text like No cases were found with give case id in case there is no match found.
I'm trying to display JSON data on my webpage by using the v-for function in Vue.js and Axios to get the data. Below is my code and an example of the JSON data i'm trying to use.
I have kept the JSON data URL out on purpose as it's private, which is why i've provided an example of the data structure.
I can print the entire data set to my page, as it appears below but if i use my code below to print specific parts of data, like the id or name, that's when i get nothing on the page.
<div id="root">
<p v-for="item in items">{{ item.name }}</p>
</div>
<script>
var app = new Vue({
el: '#root',
data: {
items: []
},
mounted() {
axios.get("...")
.then(response => {this.items = response.data.data})
}
});
</script>
JSON data example:
json
{
"current_page": 1,
"data": [
{
"id": "83",
"name": "Name1",
},
{
"id": "78",
"name": "Name2",
},
{
"id": "720",
"name": "Name3",
},
{
"id": "707",
"name": "Name4",
},
{
"id": "708",
"name": "Name5",
}
],
"from": 1,
"prev_page_url": null,
"to": 20,
"total": 42
}
looking at the code everything looks ok, but i have an example in the application i am working on and i've noticed that your items array should contain response.data.data.data wich is verbose but you can work on that later
I try to pass a JSON as String from my Spring Controller to the React Frontend.
JSON:
{
"name": ".",
"size": 0,
"children": [
{
"name": "setup.bat",
"size": 6,
"children": []
},
{
"name": "src",
"size": 0,
"children": [
{
"name": "main",
"size": 0,
"children": [
{
"name": "java",
"size": 0,
"children": [
...
I try it with Thymeleaf and the console output on my site worked:
index.html
$( document ).ready(function() {
var jsondata = /*[[${jsondata}]]*/;
console.debug(jsondata);
});
but now i try to used it in react I get an error:
app.js:
class App extends Component {
render() {
return(
<div>
{jsondata}
</div>
)
}
}
Uncaught ReferenceError: jsondata is not defined
What is the Problem in React ?
Set and access the JSON on directly on the window object.
window.jsondata = /*[[${jsondata}]]*/;
class App extends Component {
render() {
return(
<div>
{window.jsondata}
</div>
)
}
}
Solution:
I can use the Javascript var with my React code, but the Problem was in my html file. I make a wrong order of the scripts.
If i use the React bundle at the end it works:
index.html:
<script th:inline="javascript">
var jsondata = /*[[${jsonHierarchy}]]*/;
console.log(jsondata);
</script>
<script src="/bundle.js"></script>
got this json file:
[
{
"name": "paprika",
"imgSrc": "img/paprika.jpg"
},
{
"name": "kurkku",
"imgSrc": "img/kurkku.jpg"
},
{
"name": "porkkana",
"imgSrc": "img/porkkana.jpg"
},
{
"name": "lehtisalaatti",
"imgSrc": "img/lehtisalaatti.jpg"
},
{
"name": "parsakaali",
"imgSrc": "img/parsakaali.jpg"
},
{
"name": "sipula",
"imgSrc": "img/sipuli.jpg"
},
{
"name": "peruna",
"imgSrc": "img/peruna.jpg"
},
{
"name": "soijapapu",
"imgSrc": "img/soijapapu.jpg"
},
{
"name": "pinaatti",
"imgSrc": "img/pinaatti.jpg"
}
]
Which I successfully fetch in a factory:
factory('getJson', ['$resource', function($resource) {
return $resource('json/vegs.json', {}, {
query: {method:'GET', isArray:true}
});
}]);
in my Controller I can get the json's file content:
var vegs = getJson.query();
$scope.vegs = vegs;
console.log(vegs)
console.log(typeof vegs)
The weird part is the first console.log produces an array of objects, as expected.
The second console says it's an "object", and not an array.
I can get the .json content to my view using {{vegs}}, and I can use ng-repeat as well, tho in the controller I can't do vegs[0] or vegs.length. It comes out empty.
I'm breaking my head on this for over 3 hours now :)
This isn't an 'answer'. Just an observation on one part of your issue. (Sorry, can't comment yet...new to stackoverflow).
Just a note on your comment that "The second console says it's an "object", and not an array." Using typeof on an array will always return "object".
There are various (and debated, it seems) ways to test if it's an array--Array.isArray(obj) for example.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray