Cannot render values in django template using for loop - django

So i have a zipped list inside my view and I have passed it into context like this:
combined_data = zip(hostnames_list, values, values1, values2, values3, values4, values5)
context = {'combined_data': combined_data}
return render(request, 'base/snmp-table.html', context)
but when i try to render this data into the django template like this, the data is not displayed:
<table>
<thead>
<tr>
<th>Hostname</th>
<th>Value1</th>
<th>Value2</th>
<th>Value3</th>
<th>Value4</th>
<th>Value5</th>
<th>Value6</th>
</tr>
</thead>
<tbody>
{% for host, val1, val2, val3, val4, val5, val6 in combined_data %}
<tr>
<td>{{host}}</td>
<td>{{val1}}</td>
<td>{{val2}}</td>
<td>{{val3}}</td>
<td>{{val4}}</td>
<td>{{val5}}</td>
<td>{{val6}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</table>
<script type="text/javascript">
setTimeout(function () {
location.reload();
}, 2 * 1000);
</script>
The lists which are zipped are not empty because when i do this inside my view:
for host, val1, val2, val3, val4, val5, val6 in combined_data:
print(host, val1, val2, val3, val4, val5, val6)
I get the output in my console
10.1.1.1 not found not found not found not found not found not found
10.1.1.2 not found not found not found not found not found not found
Note: 'not found' is the value inside list. Any insight please? thank you

The problem was that the zip function returns an iterator, which can only be iterated over once. To fix this, you can convert the zipped object to a list by using the list() function, like so:
combined_data = list(zip(hostnames_list, values, values1, values2, values3, values4, values5))
This way, you can iterate over the combined_data variable multiple times in your template.

Related

Postman visualization: Can I create conditional statements?

I am returning a JSON body from an API using postman. I am using the visualization feature of Postman to create a template to organize and loop through the data. https://learning.postman.com/docs/sending-requests/visualizer/
Question: Can I create conditional statements? Test for the value of certain elements? The handlebars features do not seem to work.
Example:
{{#each response}} {{#if name = 'abc'}}
<td>ABC</td>
{{else}}
<td>{{name}}</td>
{{/if}} {{/each}}
Thanks!
You can use if blocks but not quite like that, as the syntax is slightly different. You can find more information about how these work here:
https://handlebarsjs.com/guide/builtin-helpers.html
You can use the if helper to conditionally render a block. If its argument returns false, undefined, null, "", 0, or [], Handlebars will not render the block
Just adding to Dannys answer:
https://github.com/postmanlabs/postman-app-support/issues/7373#issuecomment-601402891
As of now custom helpers are not supported so you have to do the if logic inside your script:
Example:
https://www.getpostman.com/collections/d3a91ce456800d061156
you can import this collection by clicking import link in postman
Explanation:
set get url as:
https://reqres.in/api/users?page=2
test script as :
template = `<table bgcolor="#FFFFFF">
<tr>
<th>Name</th>
<th>Email</th>
</tr>
{{#each response}}
{{#if George}}
<tr>
<td>Found george</td>
<td>{{email}}</td>
</tr>
{{/if}}
{{/each}}
</table>
`;
data =pm.response.json().data
data.map((a)=> a[a.first_name]=true)
// Set visualizer
pm.visualizer.set(template, {
// Pass the response body parsed as JSON as `data`
response: data
});
If you read the handle bar documentation :
https://handlebarsjs.com/guide/builtin-helpers.html
You can use the if helper to conditionally render a block. If its
argument returns false, undefined, null, "", 0, or [], Handlebars will
not render the block.
so here we are hacking this behavior , i am creating a key in the data object with same name as the value i am checking for
if the value doesn't exists then the element will be undefined else it will pass.

ember.js list template keeps getting bigger on each visit

Summary
I have a problem with a list displayed by Ember which keeps displaying extra rows each time it is visited. The extra rows are duplicates of those which were initially displayed.
Detail
In an Emberjs 2.13.0 app I have a model that looks like this :
import DS from 'ember-data';
export default DS.Model.extend({
cceIdentifierParent: DS.attr('string'),
cchCceIdParent: DS.attr('string'),
nodeType: DS.attr('number')
});
I have a route, 'diagcctreetoplevelonly', which looks like this :
import Ember from 'ember';
export default Ember.Route.extend({
model: function() {
return this.store.findAll('diagcctreetoplevelonly');
}
});
And a template that looks like this :
{{diag-warningbanner}}
{{#if model.length}}
<table>
<thead>
<tr>
<th>
cceIdentifierParent
</th>
<th>
cchCceIdParent
</th>
<th>
nodeType
</th>
</tr>
</thead>
<tbody>
{{#each model as |treenode|}}
<tr>
<td>
{{treenode.cceIdentifierParent}}
</td>
<td>
{{treenode.cchCceIdParent}}
</td>
<td>
{{treenode.nodeType}}
</td>
</tr>
{{/each}}
</tbody>
</table>
{{else}}
<p id="blankslate">
No Tree Nodes found
</p>
{{/if}}
{{outlet}}
That works fine the first time that 'diagcctreetoplevelonly' is visited - 12 rows are rendered - but on subsequent visits (without the underlying data having changed) the table rendered by the template has 12 extra rows for each time it has been visited.
Can anyone explain what i'm doing wrong ? Thank you.
EDIT: Thanks to the input from #Jeff and #Subtletree I was able to resolve this.
The problem was that the data returned had no 'id' attribute and when I created one the problem went away.
Because of the peculiar nature of the data it didn't actually matter what the id was and I didn't want to make changes to the backend so I created an id dynamically once the data had arrived on the client by creating a model level serializer and overriding the extractId method like this :
import ApplicationSerializer from './application';
export default ApplicationSerializer.extend({
extractId(modelClass, resourceHash) {
var arrId = [];
arrId.push(resourceHash['attributes']['cceIdentifierParent']);
arrId.push(resourceHash['attributes']['cchCceIdParent']);
arrId.push(resourceHash['attributes']['nodeType']);
var id = arrId.join('|');
return id == null || id === '' ? null : id+'';
},
});
It wouldn't have worked in all (perhaps most ?) situations but for my case this was good enough and resolved the problem.
To provide credit where it's due I got the idea for how to do this from the answer by #Casey here https://stackoverflow.com/a/35738573/364088 .
When ember-data receives records from a server it tries to match them to records already in the store by their id. If no id's are present then it can't find a match so instead of updating them it will just add them.
You could add an id to each record or could fetch the data with ajax and not use ember-data for this model.

Slice of structs to unsorted list with mustache

I have a struct.
type DataKey struct {
Id int64 `db:"id"`
UserId string `db:"user_id"`
Data string `db:"data"`
CreatedAt time.Time `db:"created_at"`
}
I create a slice of structs.
data := []DataKey{}
After doing a sql query and filling the slices I try to pass to mustache to build my list.
mustache.RenderFileInLayout("templates/datakeys.html.mustache", "templates/layout.html.mustache", user, data)))
datakeys.html.mustache
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>UserID</th>
<th>DataKey</th>
<th>CreatedAt</th>
</tr>
</thead>
{{#DataKey}}
<tr>
<td>{{Id}}</td>
<td>{{UserId}}</td>
<td>{{Data}}</td>
<td>{{CreatedAt}}</td>
</tr>
{{/DataKey}}
</table>
The only thing I get is the table header. This function does not return an error so I don't know why it didn't like the data. I have also tried passing it in as a reference.
Im not familiar with mustache but from looking at it I think the {{#DataKey}} is wrong.
From the docs:
Template:
{{#repo}}
<b>{{name}}</b>
{{/repo}}
Hash:
{
"repo": [
{ "name": "resque" },
{ "name": "hub" },
{ "name": "rip" }
]
}
Output:
<b>resque</b>
<b>hub</b>
<b>rip</b>
I'd suggest trying the following
viewModel := struct{
items []DataKey{}
}{
data
}
mustache.RenderFileInLayout("templates/datakeys.html.mustache", "templates/layout.html.mustache", user, viewModel )))
and then replace the template with
{{#items}}
<tr>
<td>{{Id}}</td>
<td>{{UserId}}</td>
<td>{{Data}}</td>
<td>{{CreatedAt}}</td>
</tr>
{{/items}}
This is untested and might not be correct, but might be worth trying. My guess is that DataKey isn't a property on the model hence it's failing to evaluate.
Edit for more clarity: In theory
viewModel := struct{
items []DataKey{}
}{
data
}
will become
{
"items": [
{...},{...} ... etc
]
}

Ember Ember.Select binding

I am trying to create a simple page where I loop through a list of phone numbers associated with a Contact. Each phone number has a "number" and a "phone_type".
I've created a View that extends Ember.Select that populates itself with a the list of phone_types. Other than that, is's just a plain Ember.Select:
export default Ember.Select.extend({
thestore: '',
optionLabelPath: 'content.code',
optionValuePath : 'content.code',
didInsertElement: function() {
var vtype = this.get("valuetype");
var vls = this.get("thestore").filter('valuelist', { type: 'phone_type' }, function(vv) {
return vv.get("type") == vtype;
});
this.set("content",vls);
}
});
Here is my code in the template using the "valuelist" view defined above.
{{#each phonenumber in model}}
<tr>
<td> {{phonenumber.number}}</td>
<td>{{phonenumber.phone_type}}</td>
<td>{{view 'valuelist' thestore=store valuetype='phone_type'
selection="{{phonenumber.phone_type}}"
value="phonenumber.phone_type" }}</td>
</tr>
{{/each}}
What I cannot figure out is how to bind the value in the dropdown to the field in each model record I am iterating through in the template. You can see I've tried various things in the code above without any luck.
The property you need is value. However, in your attempts above, you were filling it with literal strings. This happens when you provide a value wrapped in quotes ('...' or "..."). What you need is to give it an identifier, which is value without quotes. So, try this:
{{#each phonenumber in model}}
<tr>
<td>{{phonenumber.number}}</td>
<td>{{phonenumber.phone_type}}</td>
<td>{{view 'valuelist' thestore=store valuetype='phone_type'
value=phonenumber.phone_type }}</td>
</tr>
{{/each}}
As an aside, this is a very unortodox way of doing things. A view shouldn't be tied to a store. Also, I think this will cause your select to be unusable while the values load asynchronously (and potentially crash your app if there is an error).
A conventional way to do this would be to load the list of all phone_types in your setupController hook and then provide it as an argument to Select view.
Controller:
App.MyRoute = Ember.Route.extend({
//...
setupController: function (c, m) {
c.set("model", m);
c.set("phoneTypes", [
"home", "office"
// or whatever, load it from store in model hook and setup here
]);
}
});
Template:
{{#each phonenumber in model}}
<tr>
<td>{{phonenumber.number}}</td>
<td>{{phonenumber.phone_type}}</td>
<td>{{view Ember.Select
content=phoneTypes
value=phonenumber.phone_type }}</td>
</tr>
{{/each}}

Ember.js/rendering nested array content on handlebars

I have a model 'transaction' in which an array of subCategories is declared. This array is populated with transaction type objects whenever the method 'add_subcagtegory' of transactionsController is called. Now when i try to render subcategories in a nested loop(#collection), i do not get it done. The outer loop(#each) that is rendering the array controller objects is working fine. Can anyone tell how to render the subCategories array?
app.js
App.transaction=Em.Object.extend({
account:null,
date:null,
source:null,
description:null,
category:null,
flag_for_later:null,
amount:null,
category_id:null,
record_index:null,
isSubCategory:null,
subCategories:[]
});
App.transactionsController = Em.ArrayController.create({
content: [],
add_subcategory: function(param){
var records=this.toArray();
if (typeof(records[param.value -1].subCategories) === "undefined") {
records[param.value -1].subCategories = new Array();
}
var category=App.transaction.create({
account:"//",
date:"//",
source:"//",
description:"//",
category:" ",
flag_for_later:" ",
amount:null,
category_id:records[param.value -1].subCategories.length + 1,
isSubCategory:true
});
records[param.value -1].subCategories.push(category);
App.transactionsController.set('content',[]);
App.transactionsController.pushObjects(records);
App.array.push(obj1);
}
});
and the template:
<table>
{{#each App.transactionsController}}
<tr>
<td>{{account}}</td>
<td>{{date}}</td>
<td>{{source}}</td>
<td>{{view App.TextField class="span12" style="border:0px;" objcount=record_index fieldname="description" value=description}}</td>
<td>{{view App.TextField class="span12" style="border:0px;" objcount=record_index fieldname="category" value=category }}</td>
<td><button onclick="App.transactionsController.add_subcategory(this);" value="{{unbound record_index}}">+</button></td>
<td>{{view App.TextField class="span6" style="border:0px;" objcount=record_index fieldname="flag_for_later" value=flag_for_later }}</td>
<td>{{amount}}</td>
</tr>
{{#collection contentBinding="App.transactionsController.subCategories"}}
<b>content does,nt not render</b>
{{/collection}}
{{/each}}
</table>
in the template under collection,How can I access subCategories?
http://jsfiddle.net/KbN47/29/
Does simply binding the content of the {{collection}} helper to this.subcategories (this is a transaction in your context) work ?
{{#collection contentBinding="this.subcategories"}}
Update
Here is a jsfiddle: http://jsfiddle.net/Sly7/tRbZC/
Please note the ember version is the latest-one. You should update, as the 0.9.5 is very old.
I didn't have a look of the <select> behavior, but if it does'nt work, I think you have now all the keys to make it works :)
I modified the ember version from latest to pre 1.0 and the clicking on the + works.
http://jsfiddle.net/y3YX9/