Emberjs: Data binding breaks in inner loop - ember.js

I'm having an issue with data from my model not being bound. The category in the first each loop is bound fine. If I make a change to the input box, my model reflects that change.
The problem appears to be in the inner each loop. None of my changes in the inner loop are reflected in the model. If I change the inner loop to be just {{#each descriptions}} and use {{this}} instead of {{description}} my model still doesn't reflect the changes.
{{#each amenities}}
{{input type="text" value=category}}
<div><label>{{category}}</label></div>
<ul class="sortable-amenities" style="list-style-type: none;">
{{#each description in descriptions}}
<li>
<div>
<span class="handle glyphicon glyphicon-move pull-left" style="margin-top: 15px; margin-right: 10px;"></span>
{{input type="text" class="form-control input-amenities" name="amenity-description" placeholder="Amenity" value=description}}
<button style="padding-top: 3px;" {{action 'removeAmenity' description}}><span class="glyphicon glyphicon-remove" style=""></span></button>
</div>
</li>
{{/each}}
</ul>
{{/each}}
Sample 'amenities' I'm trying to loop through:
"amenities": [ { "category": "Featured", "_id": "53dc0aeede4be108724ce46a", "descriptions": [ "Floor Plans", "Pool", "Fitness Centre", "Air Conditioning", "Care Centre", "Pets" ] }, { "category": "Extra Features", "_id": "53dc0aeede4be108724ce469", "descriptions": [ "Three places", "Connections", "Appliances", "Breakfast", "Bright rooms", "Marble Flooring", "Ponds", "All Windows", "Organizers" ] }, { "category": "Community", "_id": "53dc0aeede4be108724ce468", "descriptions": [ "Picnic", "Basketball", "Volleyball", "Playground", "School", "Maintenance", "Customer", "Business" ] } ]

Related

How to get value from input and send it as json object to backend in vue 3

I have a questionnaire which shows questions and their answers with vuejs.
django will handle the backend.
I want to get the question id and answer from the questionnaire and send it to backend as json object.
here is my question component:
<template>
<div>
<div v-for="section in sections.slice(sectionStart, sectionEnd)" :key="section.id">
<div v-for="question in section.questions" :key="question.id">
<!-- Single Choice -->
<div v-show="question.type === 'Single Choice'" :id="question.id">
<p class="py-4 font-medium leading-8">{{ question.question_text }}</p>
<input type="hidden" :value="question.question_text" v-model="question.id">
<div class="flex py-1" v-for="choice in question.choices" :key="choice.id">
<input class="h-5 w-5" type="radio" :name="question.id" v-model="choice.id" :id="choice.id"/>
<label class="ml-3" :for="choice.id">{{ choice.text }}</label>
</div>
</div>
<!-- Multiple choice -->
<div v-show="question.type === 'Multiple Choice'" :id="question.id">
<p class="py-4 font-medium leading-8">{{ question.question_text }}</p>
<div class="flex py-1" v-for="choice in question.choices" :key="choice.id">
<input type="checkbox" class="h-6 w-6" :name="choice.id" :id="choice.id">
<label :for="choice.id" class="ml-3">{{ choice.text }}</label>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
sections: data.sections,
}
},
props:[
'sectionStart',
'sectionEnd'
]
};
</script>
Update 1
data.sections comes from django:
{% block extrahead %}
{% render_bundle 'index' 'css' %}
<script> let data = {{ data|safe }};</script>
{% endblock %}
and the structure of data:
{
section: [
0: {
id: 0,
desc: "...",
questions: [
0: {
id: 0,
text: "question text....?",
choices: [
0: {id: 0, text: "choice 1"},
1: {id: 1, text: "choice 2"},
2: {...}
]
},
1: {...},
]
},
1: {...},
2: {...}
]
}
Update 2
the json format I want to have:
responses: {
question_id: response_id,
}
How can I get question id and it's answer and save these value to json object and then send it to backend?
First you need to set up your v-model. Currently you refer to things like v-model="choice.id" which aren't existing in your data properties. How the structure of your v-model needs to be depends on how you want to pass the data.
As an example you could pass it like you already tried, with v-model. But instead of v-model="choice.id" we use v-model="userAnswers[section.id][question.id][choice.id]" after creating it in our data properties:
data() {
return {
sections: data.sections,
userAnswers: {}
}
}
So using userAnswers[section.id][question.id][choice.id] will generate something like this:
{
0: { // First section
0: { // First question
0: false, // Choices with true or false
1: true,
2: false,
3: false
}
},
1: {
...
}
}
EDIT: Usage with the provided structure
So you provided the following structure:
responses: {
question_id: response_id,
}
This is only possible for questions with only one answer and only if every answer has an unique id outside of their section. If the first question of a section always has 0 as their id, that won't work. But if they have, thatn it is simply this: userAnswers[question.id] as v-model of the radio buttons while they to provide the response_id as their values.

Returning albums array to Ember Route But {{#each}} not working

Started learning ember. Trying to display list of albums in application.hbs. After returning the array values in Routes, I am not getting array object in {{#each}}.
Please let me know what I am doing wrong.
Routes
import Ember from 'ember';
import albums from 'bumbox/models/album-fixtures';
export default Ember.Route.extend({
model: function() {
return albums;
}
});
album-fixtures.js
export default [{
id: "1",
artwork: "images/the-morning-after.jpg",
name: "The Morning After",
artist: "GOLDHOUSE",
isExplicit: false,
songs: [ "11", "12", "13", "14" ]
}, {
id: "2",
artwork: "images/dusk-to-dawn.jpg",
name: "Dusk to Dawn",
artist: "Emancipator",
isExplicit: false,
songs: [ "21", "22", "23", "24" ]
}, {
id: "3",
artwork: "images/the-heist.jpg",
name: "The Heist",
artist: "Macklemore & Ryan Lewis",
isExplicit: true,
songs: [ "31", "32", "33", "34" ]
}, {
id: "4",
artwork: "images/some-nights.jpg",
name: "Some Nights",
artist: "fun.",
isExplicit: true,
songs: [ "41", "42", "43", "44" ]
}];
application.hsb
<div class="album-list">
{{#each}}
<div class="album">
<a class="ember-view" href="/album/1">
<img src="{{artwork}}">
</a>
<p class="album-name">{{name}}</p>
<p class="album-artist">{{artist}}</p>
<p class="song-count">{{songs}}</p>
</div>
{{/each}}
</div>
You need to use {{#each model as |album|}} to iterate the model array.
The template should look like this:
{{#each model as |album|}}
<div class="album">
<a class="ember-view" href="/album/1">
<img src="{{album.artwork}}">
</a>
<p class="album-name">{{album.name}}</p>
<p class="album-artist">{{album.artist}}</p>
<p class="song-count">{{album.songs}}</p>
</div>
{{/each}}
Twiddle Example https://ember-twiddle.com/e1257c2778df8eb46168da67b02ab13c?openFiles=templates.application.hbs%2C

How do I use Meteor's Spacebar helpers within a template?

Using meteor, I'm trying to populate a list of tasks within a template. This will render the tasks just fine:
<body>
<div class="container">
<ul>
{{#each tasks}}
{{> task}}
{{/each}}
</ul>
</div>
</body>
This is a separate template task.html
<template name="task">
<li>{{text}}</li>
</template>
But once I wrap it in a home template so that I may route it appropriately it no longer shows up:
<template name="home">
<body>
<div class="container">
<ul>
{{#each tasks}}
{{> task}}
{{/each}}
</ul>
</div>
</body>
</template>
Why is this? Below is the client side js, masterLayout template, and router.js.
Template.body.helpers({
tasks: [
{ text: "This is task 1" },
{ text: "This is sk 2" },
{ text: "This is task 3" }
]
});
<template name="masterLayout">
{{> yield region='nav'}}
<div id="content">
{{> yield}}
</div>
{{> yield region='footer'}}
</template>
Router.map(function() {
this.route('home', {
path: '/',
});
this.route('private');
this.route('testing');
});
I figured it out. You need to change the middle word home to the template you are referencing. https://www.meteor.com/tutorials/blaze/templates
Template.home.helpers({
tasks: [
{ text: "This is task 1" },
{ text: "This is sk 2" },
{ text: "This is task 3" }
]
});

Multidimensional Dict or Tuple?

i have a little issue which should be easy to fix, however i'm stuck.
I have the following situation the first zip shows a timeline post.
Each timeline post could have one comment or more comments or none at all.
I first tried to do it with jquery but got stuck as well.
So to make sure the right post gets the right comment/s i compare the id from the post_id and the org_post_id.
However the loop inside the template only occurs once and it's painfully inefficient.
I think a multi dic or tuple could work but i simply can't find an answer on how to fill it.
Would someone please help ?
Thanks =)
template:
<div class="col-md-12">
<section id="cd-timeline" class="cd-container">
{% for item in merged %}
<div class="cd-timeline-block">
<div class="cd-timeline-img cd-success">
<i class="fa fa-tag"></i>
</div> <!-- cd-timeline-img -->
<div class="cd-timeline-content">
<h2>{{item.2}}</h2>
<p>{{item.6|safe}}</p>
{% if item.3 != '<p> </p>'%}
<p> <img src="{{item.2|safe}}"/> {% endif %} <p> {{item.4|safe}} {{item.5|safe}} </p> </p>
<span class="cd-date">Jan 14</span>
<div class="timeline-item-post">
<div class="timeline-options">
<i class="icon-like"></i> {{item.7}}
<button class="myEvent" id="{{item.9}}"><i class="icon-bubble"></i> {{item.8}} </button>
<i class="icon-share"></i> {{item.9}}
</div>
{% for items in comment_data %}
{% if item.0 == items.0 %}
<div class="timeline-comment">
<div class="timeline-comment-header">
<img src="assets/images/avatar2.png" alt="">
<p> {{items.1}}<small>3 hours ago</small></p>
</div>
<p class="timeline-comment-text">{{items.2}}</p>
</div>
{% endif %}
{% endfor %}
<textarea class="form-control" placeholder="Replay"></textarea>
</div>
</div> <!-- cd-timeline-content -->
</div> <!-- cd-timeline-block -->
{% endfor %}
</section> <!-- cd-timeline -->
</div>
JSON snippet:
},
"id": "511524265623184_705647176210891",
"full_picture": "https://scontent.xx.fbcdn.net/hphotos-xpt1/v/t1.0-9/p720x720/11261437_705647176210891_75015310411838465_n.jpg?oh=f8542855ab46099ea38014411e712ae7&oe=561979D9",
"from": {
"id": "511524265623184",
"category_list": [
{
"name": "Bar",
"id": "110290705711626"
}
],
"name": "Roberto American Bar",
"category": "Bar"
},
"name": "Roberto American Bar",
"comments": {
"paging": {
"cursors": {
"before": "Mw==",
"after": "MQ=="
}
},
"summary": {
"total_count": 3,
"order": "ranked"
},
"data": [
{
"user_likes": false,
"created_time": "2015-05-20T20:05:31+0000",
"message": "Mint julep hat gewonnen \ud83c\udf8a\u2728\ud83d\udc90",
"id": "705647176210891_705801926195416",
"can_remove": true,
"like_count": 3,
"from": {
"id": "511524265623184",
"category_list": [
{
"name": "Bar",
"id": "110290705711626"
}
],
"name": "Roberto American Bar",
"category": "Bar"
}
},
{
"user_likes": false,
"created_time": "2015-05-20T14:24:16+0000",
"message": "eher ein mint julep; oder? Prost, auf alle f\u00e4lle!",
"id": "705647176210891_705654729543469",
"can_remove": true,
"like_count": 2,
"from": {
"name": "Gregor Tom Imhof",
"id": "991783270834753"
}
},
{
"user_likes": false,
"created_time": "2015-05-20T13:46:33+0000",
"message": "Prince of Wales, klassisch im Silberbecher.",
"id": "705647176210891_705648629544079",
"can_remove": true,
"like_count": 0,
"from": {
"name": "Klement Cabana",
"id": "10200893066687095"
}
}
]
}
}
VIEW:
for i in feed:
try:
comments.append(i['comments']['summary']['total_count'])
if i['comments']['data'] != []:
for n in i['comments']['data']:
org_post_ids, comment_id = n['id'].split('_')
org_post_id.append(org_post_ids)
comments_name.append(n['from']['name'])
comments_message.append(n['message'])
#comments_data.append(i['comments']['data'][0]['message'])
except KeyError:
comments.append('0')
show(org_post_id)
comment_data = zip(org_post_id, comments_name, comments_message)
for i in feed:
try:
likes.append(i['likes']['summary']['total_count'])
except KeyError:
likes.append('0')
for i in feed:
try:
picture.append(i['full_picture'])
except KeyError:
picture.append('<p> </p>')
for i in feed:
try:
little_des.append(i['name'])
except KeyError:
little_des.append('<p> </p>')
for i in feed:
try:
description.append(i['description'])
except KeyError:
description.append('<p> </p>')
for i in feed:
try:
message.append(i['message'])
except KeyError:
message.append('<p> </p>')
for i in feed:
name.append(i['from']['name'])
merged = zip(post_id ,profile, name, picture, little_des, description, message, likes, comments, shares)

Json data to output handlebars ember

I'm trying to output json data with handlebars now everything is working except for the rooms price and i can not seem to find why it's not working.
In the handle bar tutorial there almost trying to do the same stuff
The json data:
[
{
"Id": 204448,
"Name": "Albus Hotel Amsterdam City Centre",
"ImageUrls": [],
"Volatility": 0,
"Address": "Vijzelstraat 49",
"Rooms": [
{
"Id": 0,
"Name": "Family Suite, 1 King Bed with Sofabed",
"IsRefundable": false,
"IsBreakfastIncluded": false,
"Price": 2437.02,
"Amenities": []
}
]
}
]
The html:
<ul>
{{#each}}
<li>
<div class="hotel_id">{{Id}}</div>
<div class="hotel_name">{{Name}}</div>
<div class="hotel_address">{{Address}}</div>
<div class="hotel_volatility">{{Volatility}}</div>
<ul>
{{#each Rooms}}
<li>
<div class="room_id">{{Price}}</div>
</li>
{{/each}}
</ul>
</li>
{{/each}}
</ul>
Output:
204448
Albus Hotel Amsterdam City Centre
Vijzelstraat 49
0
Ember is quite strict with capitalization apparantly: Nested HandlebarsJS #each helpers with EmberJS not working. You could write a JSON postprocessor or preprocessor.
Naming conventions in Ember: http://emberjs.com/guides/concepts/naming-conventions/