Variable in hugo theme not working as expected - hugo

I got an issue recently and I can’t resolve it on my own.
In my code $locale returns current language, the default is en
{{ $locale := .Site.Language.Lang }}
following that, I checked that outputs of two following expressions
{{ (index .Site.Data $locale).nav.sidebar.navItems }}
{{ (index .Site.Data "en").nav.sidebar.navItems }}
return correctly the same data.
sidebar.json file looks like this:
{
"navItems": [
{
"id": 1,
"title": "Parent",
"url": "/",
"parent": null
},
{
"id": 2,
"title": "Child",
"url": "/",
"parent": {
"id": 1
}
},
...
]
}
In code below
{{ $menus := (index .Site.Data $locale).nav.sidebar.navItems }}
{{ $mainMenus := where $menus "parent" nil }}
I get error error calling where: can't iterate over <nil>
but when I change it for
{{ $menus := (index .Site.Data "en").nav.sidebar.navItems }}
result is as expected.
I don't want to have languages hardcoded due to other languages I will use in my app.

I created such workaround:
{{ $locale := .Site.Language.Lang }}
{{ $menus := (index .Site.Data $locale).nav.footer.navItems }}
{{ $mainMenus := slice }}
{{ $subMenus := slice }}
{{ range $menus }}
{{ if (isset .parent "id") }}
{{ $subMenus = $subMenus | append . }}
{{ else }}
{{ $mainMenus = $mainMenus | append . }}
{{ end }}
{{ end }}
but I'm still confused why locale variable didn't work with where function.

Related

How to query site data in hugo using where

In a hugo template how can I do a lookup on .Site.Data. Assuming I have a data structure like this:
{
"my-blog-post": {
"Version": 21,
"Revision": 0,
"Code": "my-blog-post",
"Name": "My Blog Post",
"Parent": "the-parent-post"
},
"another-post": {
"Version": 21,
"Revision": 0,
"Code": "another-post",
"Name": "Another Post",
"Parent": "the-parent-post"
}
}
Inside the detail page for a blog post, I would like to get the list of all the posts that have the current post as the parent. Basically I would like to query posts that have "the-parent-post" as the value of Parent field.
I can achieve this using range but I need to get them using where.
I experimented with expressions like this but no joy.
{{$child_posts := where (where .Site.Data "Section" "blog") "Parent" "the-parent-post" }}
I can do this:
{{$posts := where $site.Pages "Section" "blog"}}
{{ range sort $posts "Name" "asc" }}
{{ $post := . }}
{{if eq $post.parent $currentPage.Code}}
...Do something...
{{end}}
{{end}}
But it is not ideal and not what I need.
Thanks in advance.
Your are trying to range through a map of maps. You need an array of maps.
https://discourse.gohugo.io/t/filtering-data-in-json-using-where/35287/2

ng-repeat not displaying the individual items

When running the code below in my angular 1.x app I can see the first line returns the following :
[ { "id": 121, "valid": true }, { "id": 123431, "valid": false } ]
However when I try to display the valid or id property in the ng-repeat on the following line I see nothing whatsoever? What am i doing wrong??
{{ allItems | json }}
<div ng-repeat="item in allItems">
{{ item.valid }}
</div>

Ionic 2 Angular 2 Display Data from Array of Objects

I am attempting to create a 'simple' Ionic 2 / Angular 2 Application that provides information to voters from a Google CivicInfo API Call. Users submit their address and a Ionic2/Angular2 service provider takes the form params and creates a url query string. The response is put into an Observable.
CivicInfoProvider.ts
return this.http.get(this.BASE_URL, { search: params })
.toPromise()
.then(response => response.json() as UserData[], err => console.log(err));
With the response as a JSON Observable the user is taken to the Civic Info Listing page where the data is displayed for the user.
CivicInfoList.ts
constructor(
public navCtrl: NavController,
public navParams: NavParams,
private info: CivicInfoProvider ) {
this.addr.street = this.navParams.get('street');
this.addr.city = this.navParams.get('city');
this.addr.state = 'PA';
this.addr.zip = this.navParams.get('zip');
this.searchString = this.addr.street + ' ' +
this.addr.city + ' ' +
this.addr.state + ' ' +
this.addr.zip;
this.userdata = this.info.getCivicInfo(this.searchString);
}
CivicInfoList.html
<ion-content padding>
<h6>Search Results For:</h6>
{{ (userdata | async)?.normalizedInput?.line1 }}
{{ (userdata | async)?.normalizedInput?.city }}
{{ (userdata | async)?.normalizedInput?.state }}
{{ (userdata | async)?.normalizedInput?.zip }}
<h6>Election Details:</h6>
<ion-list lines>
<ion-item>
Name: {{ (userdata | async)?.election?.name }}
</ion-item>
<ion-item>
Date: {{ (userdata | async)?.election?.electionDay }}
</ion-item>
</ion-list>
<h6>Your Polling Location:</h6>
<ion-item ngFor="location of userdata.pollingLocations">
{{ location }}
</ion-item>
<h6>Contests:</h6>
<ion-list lines>
<ion-item ngFor="contest of userdata.contests, [value]='object'">
{{ contest }}
</ion-item>
</ion-list>
</ion-content>
MY PROBLEM :: I CAN NOT figure out how to display the Objects that are stored in arrays pollingLocations from the JSON example below. I can display normalizedInput ...
In true Angular fashion there are no error messages or cryptic messages that do not lead to any help in documentation or Google searches.
Selectioned API Response
{
"kind": "civicinfo#voterInfoResponse",
"election": {
"id": "2000",
"name": "VIP Test Election",
"electionDay": "2017-06-06",
"ocdDivisionId": "ocd-division/country:us"
},
"normalizedInput": {
"line1": "911 Merrybell Lane",
"city": "Kennett Square",
"state": "PA",
"zip": "19348"
},
"pollingLocations": [
{
"address": {
"locationName": "KENNETT TOWNSHIP BLDG",
"line1": "801 BURROWS RUN RD",
"city": "CHADDS FORD",
"state": "PA",
"zip": ""
},
"notes": "",
"pollingHours": "",
"sources": [
{
"name": "Voting Information Project",
"official": true
}
]
}
],
Thanks for Your Help!
Screen Snap
Your json does not have an array of objects, you should use like this,
<ul>
<li *ng-for="#person of people.pollingLocations">
{{person.address | json}}}
</li>
</ul>
DEMO

ng-repeat inside document with specific ID

I've a document with array inside eg.:
$scope.items = [
{
"id": 1,
"name": "Apple"
"types": [{
"color": "red"
"size": "xxl
},
{
"color: "green"
"size": "S"
}]
},
{
...
}]
And i'd like to display all records from Array "types" only for items ID = 1.
I tried this (doesn't work):
table(style="width:100%")
tr(ng-repeat="type in items.types" ng-if="items.id==1")
td
p {{ type.color}}
td
p {{ type.size}}
This can be easily implement by having two ng-repeat with filter, which will filter out the items which has id 1, and do ng-repeat on that types collection.
table(style="width:100%")
tbody(ng-repeat="item in items | filter: {id: 1 }: true")
tr(ng-repeat="type in items.types")
td
p {{ type.color}}
td
p {{ type.size}}

AngularJS push to array parse in view

I have a controller where I declare the model like this:
$scope.Model =[];
after I make a rest call and the result I push it to the model:
$scope.Model.push(results.data);
The data returned can be in different length and size:
Name
Email
Items
Item 1
Item 2
Item n
Roles
Role 1
Role 2
Role n
What is the best practice of handling this with arrays in AngularJS and using ng-repeat in view in order to show the data?
Should I declare my array like this:
$scope.Model =[];
and push the results:
$scope.Model.push(results.data);
or like this:
$scope.Model =[{
Name: '',
Email: '',
Items: [{
Id: '',
Name: '',
Price: ''
}],
Roles: [{
Id: '',
Name: ''
}],
}];
and asign the results:
$scope.Model = results.data;
It is based on your response and scenarios. but ng-repeat expects Array or Array list.
1) Array
Example 1 (plain array response)
$scope.names= ["Apple", "Banana", "Orange"];
<ul>
<li ng-repeat="x in names">
{{ x }}
</li>
</ul>
Example 2 (Object response that has array)
$scope.names= {
"fruits": ["Apple", "Banana", "Orange"]
};
<ul>
<li ng-repeat="x in names.fruits">
{{ x }}
</li>
</ul>
2) Array List
Example 1 (plain array list response)
$scope.names = [{
"id": "1",
"name": "Asik"
},
{
"id": "1",
"name": "John"
},
{
"id": "1",
"name": "Smith"
}];
<ul>
<li ng-repeat="x in names">
id:{{ x.id }}, name:{{ x.name }}
</li>
</ul>
Example 2 (Object response that has array list)
$scope.names = {
"success": "true",
"items": [{
"id": "1",
"name": "Asik"
},
{
"id": "1",
"name": "John"
},
{
"id": "1",
"name": "Smith"
}]
};
<ul>
<li ng-repeat="x in names.items">
id:{{ x.id }}, name:{{ x.name }}
</li>
</ul>
Basically, service/ajax response comes as Array or Array list. So you don't need to do the following steps.
$scope.Model =[];
$scope.Model.push(results.data);
But the above case comes in some situation (for eg: merging 2 service/ajax responses )
I have used the following:
angular.copy(results.data, $scope.Model)
This will actually copy the results from the rest servicve into my model without having to declare each property of the model.

Resources