Nunjucks nested object array field printing - templating

My array data:
data = [
{ field: { name:"name1", title:"title1" } },
{ field: { name:"name2", title:"title2" } },
{ field: { name:"name3", title:"title3" } }
];
I want to write name fields like this:
Expected Output
name1.name2.name3
I need join these object's specified field values but I don't know how to get them like this.
What I tried and failed =>
data | selectattr("field") | selectattr("name") | join(".") }}

selectattr-filter only filter data elements. Therefore, when you apply selectattr('name'), nunjucks try to filter data by elements having name-field (none of them) and returns the empty result.
The simplest way to achive name1.name2.name3 is to use a custom filter
const nunjucks = require('nunjucks');
const env = nunjucks.configure();
env.addFilter('map', function (arr, prop, ...etc) {
const f = typeof prop == 'function' ?
prop : typeof env.filters[prop] == 'function' ?
env.filters[prop] : (e) => e[prop];
return arr instanceof Array && arr.map(e => f(e, ...etc)) || arr;
});
const data = [
{field: {name: "name1", title: "title1"}},
{field: {name: "name2", title: "title2"}},
{field: {name: "name3", title: "title3"}}
];
const html = env.renderString(`{{ data | map('field') | map('name') | join('.') }}`, {data});
console.log(html);

Related

ChartJs Uncaught ReferenceError for labels value from ViewBag

I'm struggling with passing the csv strings via ViewBag in the correct format.
I know the result should be like ["Blue","Brown","Green"] but my script is generated as [Blue,Brown,Green] instead.
And then I get the Uncaught ReferenceError : Blue is not defined.
How can I format it in my controller to pass in the correct way?
This is my code in the controller
public ActionResult Index()
{
List<string> teamsList = new List<string>();
List<string> salesCount = new List<string>();
foreach (var team in Db.Teams)
{
teamsList.Add(team.Name);
int count = Db.LeadCampaigns.Count(i => Db.Agents.FirstOrDefault(a => a.AgentId == i.AgentId).TeamId == team.TeamId && i.LeadStatusId == Db.LeadStatuses.FirstOrDefault(s => s.Name == "SALE").LeadStatusId);
salesCount.Add(count.ToString());
}
ViewBag.SaleCount_List = string.Join(",", salesCount);
ViewBag.TeamName_List = string.Join(",", teamsList);
return View();
}
And here is my script in the view.
<script>
var barChartData =
{
labels: [#Html.Raw(ViewBag.TeamName_List)],
datasets: [{
label: 'TeamWise Sales Count',
backgroundColor: [
"#f990a7",
"#aad2ed",
"#9966FF",
"#99e5e5",
"#f7bd83",
],
borderWidth: 2,
data: [#ViewBag.SaleCount_List]
}]
};
window.onload = function () {
var ctx1 = document.getElementById("barcanvas").getContext("2d");
window.myBar = new Chart(ctx1,
{
type: 'bar',
data: barChartData,
options:
{
title:
{
display: true,
text: "TeamWise Sales Count"
},
responsive: true,
maintainAspectRatio: true
}
});
}
Your plugin expects an array of values, but your passing it a string by using String.Join().
Pass the array using
ViewBag.SaleCount_List = salesCount;
ViewBag.TeamName_List = teamsList;
(or better pass a view model with 2 IEnumerable<string> properties) and then convert it to a jacascript array
var saleCounts = #Html.Raw(Json.Encode(ViewBag.SaleCount_List))
var teamNames = #Html.Raw(Json.Encode(ViewBag.TeamName_List))
var barChartData =
{
labels: teamNames,
datasets: [{
....
],
borderWidth: 2,
data: saleCounts
}]
};
Using your current syntax:
const string quote = "\"";
foreach (var team in Db.Teams)
{
teamsList.Add(quote + team.Name + quote);
int count = Db.LeadCampaigns.Count(i => Db.Agents.FirstOrDefault(a => a.AgentId == i.AgentId).TeamId == team.TeamId && i.LeadStatusId == Db.LeadStatuses.FirstOrDefault(s => s.Name == "SALE").LeadStatusId);
salesCount.Add(count.ToString());
}

How to add sorting for field object of graphql type which refers to different graphql type?

I am using Neo4j dB and using pattern comprehension to return the values. I have 2 types Person and Friend:
(p:Person)-[:FRIEND_WITH]->(f:Friend)
Type Person{
id: String
name: String
friends: [Friend]
}
Type Friend{
id: String
name: String
}
type Query {
persons( limit:Int = 10): [Person]
friends( limit:Int = 10): [Friend]
}
What i want to do is to pull the array list of field friends (present in Person Type) in ascending order when the "persons" query executes. For e.g.
{
"data": {
"persons": {
"id": "1",
"name": "Timothy",
"friends": [
{
"id": "c3ef473",
"name": "Adam",
},
{
"id": "ef4e373",
"name": "Bryan",
},
(
"id": "e373ln45",
"name": "Craig",
},
How should I do it ? I researched regarding the sorting, but I did not find anything specific on the array object's sorting when we are using pattern comprehension in neo4j. Any suggestions would be really helpful !
I used the sortBy function of lodash to return the result into an ascending order.
And here is the graphql resolver query:
persons(_, params) {
let query = `MATCH (p:Person)
RETURN p{
.id,
.name,
friends: [(p)-[:FRIEND_WITH]->(f:Friend)) | f{.*}]
}
LIMIT $limit;`;
return dbSession().run(query, params)
.then(result => {
return result.records.map(record => {
let item = record.get("p");
item.friends = sortBy(item.friends, [function(i) {
return i.name;
}]);
return item;
})
})
}

Falcor - HTTPDataSource to post Json

Is it possible to post a Json file using the falcor.browser's model? I have used the get method in it. Below is what I require, but it is not working.
<script src="./js/falcor.browser.js"></script>
function registerUser() {
var dataSource = new falcor.HttpDataSource("http://localhost/registerUser.json");
var model = new falcor.Model({
source: dataSource
});
var userJson = {"name":"John","age":"35","email":"john#abc.com"};
model.
set(userJson).
then(function(done){
console.log(done);
});
This is the server.js code:
app.use('/registerUser.json', falcorExpress.dataSourceRoute(function (req, res) {
return new Router([
{
route: "rating",
get: function() {
// Post call to external Api goes here
}
}
]);
}));
A few things:
The Model's set() method takes 1+ pathValues, so reformat your userJson object literal into a set of pathValues. Something like:
model.
set(
{ path: ['users', 'id1', 'name'], value: 'John' },
{ path: ['users', 'id1', 'age'], value: 35 },
{ path: ['users', 'id1', 'email'], value: 'john#abc.com' }
).
then(function(done){
console.log(done);
});
Second, your router must implement set handlers to correspond to the paths you are trying to set. These handlers should also return pathValues:
new Router([
{
route: 'users[{keys:ids}]["name", "age", "email"]',
set: function(jsonGraph) {
// jsonGraph looks like { users: { id1: { name: "John", age: 35, email: "john#abc.com" }
// make request to update name/age/email fields and return updated pathValues, e.g.
return [
{ path: ['users', 'id1', 'name'], value: 'John' },
{ path: ['users', 'id1', 'age'], value: 35 },
{ path: ['users', 'id1', 'email'], value: 'john#abc.com' },
];
}
}
]);
Given that your DB request is likely asynchronous, your route get handler will have to return a promise or observable. But the above should work as a demonstration.
Edit
You can also use route pattern matching on the third path key if the number of fields gets large, as was demonstrated above on the second id key.
{
route: 'users[{keys:ids}][{keys:fields}]',
set: function(jsonGraph) {
/* jsonGraph looks like
{
users: {
id1: { field1: "xxx", field2: "yyy", ... },
id1: { field1: "xxx", field2: "yyy", ... },
...
}
}
*/
}
}

Json Serialization Array to Object

I have a problem to serialize a json from a list of object
My goal is to have this format =>
var tag =
{
RCP: {name: "Dossier à présenter en RCP", type: "checkbox", events: {change: function(e) { console.log(e.data); console.log(e); } }, callback: function(key, opt){ console.log("key : " + key); console.log(opt); alert(opt.$trigger.attr("id")); }},
COL: {name: "Dossier à présenter en colloque", type: "checkbox", callback: function(key, opt){ console.log("key : " + key); console.log(opt); alert(opt.$trigge.attr("id")); }},
COM: {name: "Commentaire", type: "textarea", callback: function(key, opt){ console.log("key : " + key); console.log(opt); alert(opt.$trigge.attr("id")); }}
};
I'm using EF to retrieve the data as this :
var list = (from e in l_entities.TAG
where e.tag_site_code.Trim() == siteCode.Trim()
select new CvrTag
{
Id = e.tag_id,
Name = e.tag_libelle,
Type = e.tag_site_code
}
).ToList();
But I retrieve a classic Array when I use JsonConvert.SerializeObject(list).
So my question is :
- How to have braces instead array's brackets
- How to have an id (ie: RCP or COL) before the json object without quotes
- Same to inside json object (ie: name or type)
Thanks for your help
Since you are invoking ToList(), your serialization will be a list/array. If you want an object instead, use ToDict():
var dict = (from e in l_entities.TAG
where e.tag_site_code.Trim() == siteCode.Trim()
select new CvrTag
{
Id = e.tag_id,
Name = e.tag_libelle,
Type = e.tag_site_code
}
).ToDict(t => t.Id);

Entity sql datetime literal

I am stuck in the ObjectQuery class it always gives me the error as
System.Data.Entity: The argument types 'Edm.DateTime' and 'Edm.String' are incompatible for this operation., near WHERE predicate
Please suggest me the solution, i followed the above approach, but it did not work.
my code is as follows:
C# code:
var _dbModel = new VISAIntBPAEntities();
var serializer = new JavaScriptSerializer();
Filters f = (!_search || string.IsNullOrEmpty(filters)) ? null : serializer.Deserialize<Filters>(filters);
//if (f != null)
//{
// if (f.rules[0].field == "CreatedDate")
// {
// Convert.ToDateTime(f.rules[0].data).ToString();
// }
//}
ObjectQuery<Jobs> filteredQuery = (f == null ? _dbModel.Jobs : f.FilterObjectSet(_dbModel.Jobs));
//if (f != null)
//{
// if (f.rules[0].field == "CreatedDate")
// {
// filteredQuery.Parameters.Add(new ObjectParameter("CreatedDate", Convert.ToDateTime(f.rules[0].data)));
// }
//}
if (f != null)
{
DateTime dateTimeValue = Convert.ToDateTime(f.rules[0].data);
filteredQuery = filteredQuery.Where(string.Format("(it.CreatedDate = DATETIME'{0:yyyy-mm-dd hh:mm}')", dateTimeValue));
}
filteredQuery.MergeOption = MergeOption.NoTracking; // we don't want to update the data
var totalRecords = filteredQuery.Count();
Cleint side code:
this code is in built using jqgrid, which has a column called CreatedDate, which fills in the dropdown, i have a sql query which fetches me the distinct date part from the database.
I am doing filtering based on the string date selection in the dropdown.
{
name: 'CreatedDate', index: 'CreatedDate', width: 140, stype: 'select', async: false, sorttype: 'date',
edittype: 'select', editoptions: { value: getCreatedJobDate() }, editable: true, formatoptions: { newformat: 'm/d/Y' },
//editrules: { required: true },
searchoptions: {
value: getCreatedJobDate,
sopt: ['eq', 'ne', 'lt', 'le', 'gt', 'ge', 'de']
}
}
Please help me as i am stuck with this approach, i need to do this way only.
Thanks in advance.
The commented code show that you already experimented with ObjectParameter. You can do
filteredQuery = filteredQuery.Where("it.CreatedDate = #createDate");
var par = new ObjectParameter("createDate", dateTimeValue);
filteredQuery.Parameters.Add(par);
And the SQL code will show something like
DECLARE #createDate DateTime = '2002-11-06 00:00:00.000'
followed by the query itself.

Resources