How to create a bullet list from parsed dynamic object - html

So I have a JSON string foo_json_string:
[{"foo_name":"foo_value"},{"foo_name1":"foo_value1"}]
that I want to parse and show as HTML list.
I used the following approach:
<ul>
<li v-for="item in JSON.parse(foo_json_string)" v-bind:key="item.id">
{{`${item.name} = ${item.value}`}}
</li>
</ul>
This doesn't work. Most likely because item.name and item.value don't exist but I am not sure how to fix that. Any suggestions?

Maybe, you mean like this ?
var respond = [{"foo_name":"foo_value"},{"foo_name1":"foo_value1"}];
$.each(respond, function(k, v){
console.log(v);
$.each(v, function(k1, v1){
$('#out').append('<li>'+v1+'</li>');
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="out"></ul>

You need to access the key of the parsed Object. Use Object.keys() method for getting the key. There is the working snippet below.
new Vue({
el: '#app',
data: {
foo_json_string: '[{"foo_name":"foo_value"},{"foo_name1":"foo_value1"}]',
},
});
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<ul v-for="item in JSON.parse(foo_json_string)">
<li v-for="key in Object.keys(item)">
{{`${key} = ${item[key]}`}}
</li>
</ul>
</div>

Related

Using ng-repeat or ngFor to display each object in a JSON object as individual list items

I recieve an object that looks like this:
I'm trying to use ng-repeat to display the "Message", "Priority" and "DateTime" properties of each object as li items in a ul.
I've tried a couple of approaches including ng-repeat and ngFor, where all have been wrapped in divs like the first option:
This seems like the proper way to do it, but returns exactly nothing:
<div style="background: red;">
<ul>
<li ng-repeat="Notification in allNotifications">{{Notification}}</li>
</ul>
</div>
This option returns the specific object as expected:
<li style="border-radius: 3px"
[ngStyle]="{'color' : alertText}" >
Notification: {{ allNotifications.Notifications['0'].Message['0'] }}
</li>
Doesnt compile:
<li style="border-radius: 3px"
[ngStyle]="{'color' : alertText}"
[ngFor]="let subItem of allNotifications.Notifications['0'].Message['0']">
Notification: {{ subItem }}
</li>
My TS looks like this:
export class EventLogComponent implements OnInit {
constructor(private _dashdata: DashdataService) { }
NotificationName: string;
alertText: string;
allNotifications: JSON;
ngOnInit() {
this.NotificationName = 'NoNameAvailable';
this.alertText = 'Black'; //TODO: set color according to threatlevel
setInterval(() => {
this._dashdata.getAllNotifications()
.subscribe(res => {
this.allNotifications = res['notificationdata'];
console.log(this.allNotifications);
});
}, 5000); // Data Update interval in MS
}
}
ng-repeat is directive of framework AngularJS.
You are using Angular so in your case you should use ngFor:
<div style="background: red;"> <ul> <li *ngFor="let notification of allNotifications">{{notification}}</li> </ul> </div>
Using angular you should forget ng-repeat that is apart of AngularJS (version <= 1.6)
I think you have a double problem, the first one, as said, is ng-repeat, the second one is that you are not well targeting your data.
Try this
template
<div style="background: red;">
<ul>
<li *ngFor="let not of allNotifications.Notification">{{not}}</li>
</ul>
</div>

Angular 2-way binding not working

Below is my code.2 way binding is not working as expected. Can you please point-out the mistake
<div id="list" class="form-group">
<label for="attach" class="col-xs-2 control-label">{{ resource["gve.common.attach"] }}</label>
<div class="col-xs-5">
<ol class="marTop10">
<li class="exactFit" ng-repeat="files in attachList">{{ files.fileName }}</li>
</ol>
</div>
</div>
$scope.populateView = function()
{
$rootScope.inputSpin = false;
$rootScope.modifiedCaseData = $scope.problem;
$scope.showReviewBtn = $rootScope.showReviewBtn;
$scope.attachList = [];
$scope.attachList.push({fileId:"100",fileName:"Test.pdf"});
for(i in $scope.attachList) {
console.log (i, $scope.attachList[i]);
}
};
fileName is not getting displayed in HTML {{files.fileName}} even though {fileId:"100",fileName:"Test.pdf"} is added to $scope.attachList
EDIT 1: I am sorry for not mentioning those details. ng-controller is already defined and populateView() is called from a different function.
EDIT 2: From console.log .
09:56:17.486 problemCtrl.js?gccm=1.0:185 0 Object {fileId: 100, fileName: "untitled 8.txt"}fileId: 100fileName: "untitled 8.txt"
Are you missing the ng-controller directive or it is already defined elsewhere?
Make sure you are calling the populateView()
DEMO
var app = angular.module('test',[]);
app.controller('testCtrl',function($scope){
$scope.populateView = function()
{
$scope.attachList = []; $scope.attachList.push({fileId:"100",fileName:"Test.pdf"});
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test" ng-controller="testCtrl" ng-init="populateView()" class="col-xs-5">
<ol class="marTop10">
<li class="exactFit" ng-repeat="files in attachList">{{ files.fileName }}</li>
</ol>
</div>

Multi Array in Angular

I want to make multidimensional JSON array. So that when i filter the id i whould get data of the respective id:
for egs: ID 1022101 the view should be
<li>x</li>
<li>y</li>
<li>z</li>
<div ng-app="myapp">
<div ng-controller="w">
<ul ng-repeat="x in data | filter:1022101 ">
<li>{{x.file}}</li>
</ul>
</div>
</div>
controller:
var app = angular.module('myapp',[]);
app.controller('w',function($scope){
$scope.data = [
{"id":"1022101","file":["x","y","z"]},
{"id":"1022102","file":["xa","sy","fz"]}
];
});
Jsfiddle Demo
you can use | filter:{id:1022101} to filter fo the id
jsfiddle
If I understand correctly what you are trying to do then you can use something lik this:
<ul ng-repeat="(id, file) in data | filter:id:1022101 ">
<li>{{file.x}}</li>
<li>{{file.y}}</li>
</ul>
I am not 100% sure I wrote the filter correctly, but you have your value in the id so you can adjust the filter as you need.
If your file is an Json array, you can make another ng-repeat inside your ng-repeat like
<ul ng-repeat="(id, file) in data | filter:id:1022101 ">
<li ng-repeat="xFile in file">{{xFile}}</li>
</ul>

Using ng-repeat on a JSON object doesn't work - why?

I can't seem to iterate over a JSON object using ng-repeat. I did test it directly by index and it works, but just can't seem to loop and print. What am I doing wrong? JSFiddle link.
Here's my code:
<div ng-app="myApp">
<div ng-controller="Ctrl">
<h3>Upcoming Events</h3>
<ul ng-repeat="event in events">
<li>{{ event.feed.entry.title.$t }}</li>
</ul>
<!-- testing single entry here - it works! -->
<small>{{ events.feed.entry[0].title.$t }}</small>
</div>
</div>
The script:
var app = angular.module('myApp', []);
var feedUrl = 'https://www.google.com/calendar/feeds/ogmda.com_89pas0l9jbhpf053atd83hdj30%40group.calendar.google.com/public/basic?alt=json';
app.controller('Ctrl', function($http, $scope) {
$http.get(feedUrl).success(function(data) {
$scope.events = data;
});
});
That's because you iterate over the whole data returned by the calendar query, and not over the entries themselves. Change your ul to:
<ul ng-repeat="entry in events.feed.entry">
<li>{{ entry.title.$t }}</li>
</ul>

Best way to implement a tabpanel in ember?

I'm new to ember and trying to build a Ember driven web application. I've read various tuts and studies several examples. The basic concepts are clear but now I'am stuck on trying to implement a tabpanel. My approach is as follows:
View
Configurator.TabPanelView = Ember.View.extend({
classNames: ['tabPanel'],
templateName: 'tabPanel'
});
Template
<script type="text/x-handlebars" data-template-name='tabPanel'>
<div class='tabHead'>
<ul>
{{#each tabViews}}
<li {{action "{{this.actionName}}" target="{{this.value}}"}} >{{this.title}}</li>
{{/each}}
</ul>
<div class="tab-content">{{outlet}}</div>
</div>
</script>
Usage in App
var tab= Configurator.TabPanelView.create({
classNames: ['assortment'],
tabViews: [{ title: 'First', value:'Foo', actionName: 'firstTab' },{title: 'Second', value:'Foo', actionName: 'secondTab' }],
firstTab: Ember.View.extend({
templateName: 'first'
}),
secondTab: Ember.View.extend({
templateName: 'second'
})
});
tab.appendTo("body");
The TabTemplate is rendered correctly but if I try to click on the li-elements following error is thrown
Uncaught Error: assertion failed: Target <(subclass of
Ember.View):ember217> does not have action {{this.actionName}}
I'm also curious if I should use a router to implement tabbing. But as far as i can see routers act on application level and are intended to be used in single UI-compos.
The problem is in your template:
<li {{action "{{this.actionName}}" target="{{this.value}}"}} >{{this.title}}</li>
AFAIK, actions can't be bound, so when you write this, it tries to call the method {{this.actionName}} instead of firstTab, for example.
I think this is a typical example where you should use a Ember.CollectionView with an itemViewClass which has the click method, i.e.:
App.MyCollectionView = Ember.CollectionView.extend({
tagName: 'ul',
templateName: 'the-template-name',
itemViewClass: Ember.View.extend({
click: function() {
var actionName = this.get('content.actionName'),
target = this.get('controller.target');
target.send(actionName);
}
})
});
The code above is surely not right, but the idea is here.
But I think the Router is the right way to do that. I suggest you to take a look at the Ember Router example by #ghempton, where it defines tab with Ember.Router.
You have 2 options:
1) each tabpage has its own controller, view and must also be defined in the router
<script type="text/x-handlebars" data-template-name="tabs">
<div>
<ul class="nav nav-tabs">
{{#view Bootstrap.TabItem item="info"}}
<a {{action gotoInfo}}>Info</a>
{{/view}}
{{#view Bootstrap.TabItem item="anamnese"}}
<a {{action gotoAnamnese}}>Anamnese</a>
{{/view}}
{{#view Bootstrap.TabItem item="medication"}}
<a {{action gotoMedication}}>Medication</a>
{{/view}}
</ul>
{{outlet}}
</div>
</script>
Bootstrap.TabItem = Ember.View.extend({
tagName: 'li',
classNameBindings: ['isActive:active'],
isActive: function() {
return this.get('item') === this.get('controller.selectedTab');
}.property('item', 'controller.selectedTab').cacheable()
});
2) all tabpages are in one large view, and tabpages will be hidden or shown
{{#view Ember.TabContainerView currentView="info"}}
<ul class="nav nav-tabs">
{{#view Bootstrap.TabView value="info"}}<a>Info</a>{{/view}}
{{#view Bootstrap.TabView value="anamnese"}}<a>Anamnese</a>{{/view}}
{{#view Bootstrap.TabView value="medication"}}<a>Medication</a>{{/view}}
</ul>
{{#view Ember.TabPaneView viewName="info"}}
{{view EEPD.InfoView}}
{{/view}}
{{#view Ember.TabPaneView viewName="anamnese"}}
{{view EEPD.AnamneseView}}
{{/view}}
{{#view Ember.TabPaneView viewName="medication"}}
{{view EEPD.MedicationView}}
{{/view}}
{{/view}}
Bootstrap.TabView = Ember.TabView.extend({
tagName: 'li',
classNameBindings: ['isActive:active'],
isActive: function() {
return this.get('value') === this.get('tabsContainer.currentView');
}.property('tabsContainer.currentView').cacheable()
});
There are two ways to implement a tab panel.
If you want your tabs to be bookmarkable, then you should implement them using Router:
Templates
<script type="text/x-handlebars" data-template-name="application">
<div class="tabpanel">
<div class="tabs">
<div {{action "goToFirstTab"}}>First tab</div>
<div {{action "goToSecondTab"}}>Second tab</div>
</div>
{{outlet}}
</div>
</script>
<script type="text/x-handlebars" data-template-name="firstTab">
First Tab content
</script>
<script type="text/x-handlebars" data-template-name="secondTab">
Second Tab content
</script>
Code:
var App = Ember.Application.create();
App.ApplicationController = Ember.Controller.extend();
App.ApplicationView = Ember.View.extend();
App.FirstTabView = Ember.View.extend({templateName: "firstTab"});
App.FirstTabController = Ember.Controller.extend();
App.SecondTabView = Ember.View.extend({templateName: "secondTab"});
App.SecondTabController = Ember.Controller.extend();
App.Router = Ember.Router.create({
root: Ember.Route.extend({
goToFirstTab: Ember.Route.transitionTo("firstTab"),
goToSecondTab: Ember.Route.transitionTo("secondTab"),
index: Ember.Route.extend({
route: "/",
redirectsTo: "firstTab"
}),
firstTab: Ember.Route.extend({
route: "/firstTab",
connectOutlets: function (router) {
router.get('applicationController').connectOutlet('firstTab');
}
}),
secondTab: Ember.Route.extend({
route: "/secondTab",
connectOutlets: function (router) {
router.get('applicationController').connectOutlet('secondTab');
}
})
})
});
App.initialize(App.Router);
The second way, without Router.
Templates (note that actions` targets are changed)
<script type="text/x-handlebars" data-template-name="application">
<div class="tabpanel">
<div class="tabs">
<div {{action "goToFirstTab" target="controller"}}>First tab</div>
<div {{action "goToSecondTab" target="controller"}}>Second tab</div>
</div>
{{outlet}}
</div>
</script>
<script type="text/x-handlebars" data-template-name="firstTab">
First Tab content
</script>
<script type="text/x-handlebars" data-template-name="secondTab">
Second Tab content
</script>
Code (pretty much the same, except that the code related to tabs is now moved to ApplicationController.
var App = Ember.Application.create();
App.ApplicationView = Ember.View.extend();
App.Router = Ember.Route.create();
App.FirstTabView = Ember.View.extend({templateName: "firstTab"});
App.FirstTabController = Ember.Controller.extend();
App.SecondTabView = Ember.View.extend({templateName: "secondTab"});
App.SecondTabController = Ember.Controller.extend();
App.ApplicationController = Ember.Controller.extend({
view: App.FirstTabView.create(),
goToFirstTab: function () {
this.connectOutlet("firstTab");
},
goToSecondTab: function () {
this.connectOutlet("secondTab");
}
});
App.initialize(App.Router);