Ng-repeat not working expression shows and then disappears immediately - javascript

I am creating a list of users on this page using ng-repeat. When the page is refreshed the expression that is supposed to appear shows up for a split second and then disappears without any trace of the object that should be repeated. This is the code
<div class="row" data-ng-controller="createUserProfileController as dashboard">
<h2 class="text-center">Find Students Near By</h2>
<hr />
<div class="col-md-6" id="map-canvas"></div>
<div class="col-md-4 pull-right">
<div class="panel-success">
<div class="panel-heading">
<h3 class="text-center">List of Datalus Users</h3>
</div>
<hr />
<div ng-repeat="userProfile in dashboard.items" class="panel">
<div class="panel-heading">
<h4 class="panel-title text-center">
<a data-parent="#accordion1" href="/courses/moreinfo/{{userProfile.id}}">
{{userProfile.firstName}}
</a>
</h4>
</div>
</div>
</div><!-- /.cols -->
</div>
</div>

In your code there is no error. Might be you are doing changes from somewhere else. Here I implemented your code in jsfiddle.
angular.module("app", [])
.controller("createUserProfileController", ["$scope", function($scope){
var c = this;
c.items = [
{
id: 1,
firstName: 'hello'
}, {
id: 2,
firstName: 'bufellow'
}
];
}]);

Related

Nested v-for in vuejs for accordian data

I am building a small application on VueJS 2.5.17 where I am having nested accordion data which I need to display through click events, I have a hierarchy of Root -> Roles -> Specialisation -> withRoles .... and so on. I am trying to get child elements on every click of their respective parents.
Following is my HTML Code:
<div class="panel-group" id="accordion1" v-for="items in accordianData">
<div class="panel my-panel-warning">
<div class="panel-heading">
<h4 class="panel-title">
<a style="color: #000; font-size: 14px" data-toggle="collapse" data-parent="#accordion1" :href="'#'+items.id">DOCUMENTED RELATIONSHIPS ({{count}})</a>
</h4>
</div>
<div :id="items.id" class="panel-collapse collapse">
<div class="my-panel-body">
<div class="my-panel-body">
<div class="panel-group" :id="items.id" >
<div class="panel my-panel-warning" v-for="child1 in roles">
<div class="panel-heading">
<a data-toggle="collapse" :data-parent="'#'+items.id" :id="'child'+child1.id" :href="'#role'+child1.id" #click="getSpecialisation(child1.id, child1.name)">{{child1.name+" (0)"}}</a>
</div>
<div class="my-panel-body">
<div :id="'role'+child1.id" class="panel-collapse collapse">
<div class="panel my-panel-warning" v-if="child1.id === child2.parent_id" v-for="child2 in specialisations[child1.name]">
<div class="panel-heading">
<a data-toggle="collapse" :data-parent="'#role'+child1.id" :id="'child2'+child2.id" :href="'#spec'+child2.id" #click="getWithRoles(child2.id)">{{child2.name+" (0)"}}</a>
</div>
<div class="my-panel-body">
<div :id="'spec'+child2.id" class="panel-collapse collapse">
<div class="my-panel-body">
.
.
.
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
And calling following function in my methods:
getSpecialisation(id, name) {
axios.get('specialisations?company_id='+this.company_id+'&role_id='+id, {headers: getHeader()}).then(response => {
if(response.status === 200)
{
this.specialisations[name] = response.data.specialisations
}
})
},
But some how I am unable to display the data. Previously I tried v-for="child2 in specialisations" and in response I did this.specialisations = response.data.specialisations I was getting all similar child element for all parents I know this is wrong but just wanted to inform that I was getting data and my accordion was displaying child elements, but once I did according to above method getSpecialisation mentioned, I am unable to display the data.
I can see my data in vue console:
Suggest me a better way for this.
Thanks
Instead of this.specialisations[name] = response.data.specialisations try:
Vue.set(this.specialisations, name, response.data.specialisations)
That should trigger Vue's change-detection.
Ps. When you see lots of nesting, this might be good time to split a big component up into smaller components.

Close every other panel apart from the one being opened using Angular 2

I'm trying to click on a panel and open it's body attached to it. However, I'm opening all the bodies.
I've got the following HTML code:
<div id="contractModifyPanel" class="container body-content">
<div class="clearfix">
<h2>
{{ title }}
<span id="role" style="float: right;">
<button id="btnExportRateGridContract" type="button" class="btn btn-default btn-sm" onclick="">
<span class="glyphicon glyphicon-export"></span> Export Rate Grid
</button>
</span>
</h2>
</div>
<h4>{{ contractInstructions }}</h4>
<div class="panel panel-default" (click)="openBodyPanel()">
<div class="panel-heading warnOnExit">
<span class="glyphicon glyphicon-chevron-{{arrowDirection}} chevronIcon"></span>
<h3 class="panel-title">Contract Information</h3>
</div>
<div class="panel-body" *ngIf="showBody">
</div>
</div>
<div class="panel panel-default" (click)="openBodyPanel()">
<div class="panel-heading">
<span class="glyphicon glyphicon-chevron-{{arrowDirection}} chevronIcon"></span>
<h3 class="panel-title">Firm Fees</h3>
</div>
<div class="panel-body" *ngIf="showBody">
</div>
</div>
<div class="panel panel-default" (click)="openBodyPanel()">
<div class="panel-heading">
<span class="glyphicon glyphicon-chevron-{{arrowDirection}} chevronIcon"></span>
<h3 class="panel-title">Product Selection</h3>
</div>
<div class="panel-body" *ngIf="showBody">
</div>
</div>
<div class="panel panel-default" (click)="openBodyPanel()">
<div class="panel-heading">
<span class="glyphicon glyphicon-chevron-{{arrowDirection}} chevronIcon"></span>
<h3 class="panel-title">Product Level Fees</h3>
</div>
<div class="panel-body" *ngIf="showBody">
</div>
</div>
<div class="panel panel-default" (click)="openBodyPanel()">
<div class="panel-heading">
<span class="glyphicon glyphicon-chevron-{{arrowDirection}} chevronIcon"></span>
<h3 class="panel-title">Footnotes and Exceptions</h3>
</div>
<div class="panel-body" *ngIf="showBody">
</div>
</div>
</div>
And my .ts file looks like:
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'modify-contract',
templateUrl: './modify-contract.html',
styleUrls: ['./modify-contract.css']
})
export class ModifyContractComponent implements OnInit {
title: string = 'Modify Contract';
contractInstructions: string = 'Complete the following steps to create a
contract, specify firm and program fees, and assign Product(s)';
arrowDirection: string = 'right';
showBody: boolean;
openPanel: boolean;
closedPanels: boolean;
constructor() {
this.showBody = false;
}
openBodyPanel() {
this.showBody = !this.showBody;
this.arrowDirection = (this.showBody ? 'down': 'right');
}
ngOnInit() { }
}
Every time I choose to click one panel, all of the bodies underneath the specific div opens up. How would I go about opening an individual panel without creating unique identifiers? In case I end up having to create a 100 panels, I don't want to label 100 unique identifiers.
Refactor that logic into a component (which will also help clear up all that redundant copy & paste HTML), the controller instances will each have their own showBody property, independent of the other instances.
In terms of closing other panels automatically, there are multiple options:
You can use a parent component/directive that adds all child components to a list. A click on a panel could be handled by this parent which closes all its other panels and opens the one that was clicked on.
Alternatively you could use some directive with a key value which has some internal dictionary keeping track of all panels with the same key. It could then also manage this logic. You would of course have to define this kind of directive on all panels, with the same key.

AngularJS iterating through Eventbrite events

My Json file is here.
My HomeController is:
app.controller('HomeController', ['$scope', 'events', function($scope, events) {
events.then(function(data) {
$scope.events = data;
});
$scope.test="success";
}]);
and my html file is:
Home
<h1> {{test}} </h1>
<section class="container" ng-repeat="event in events">
<div class="col-sm-4" >
<div class="card">
<img class="img-responsive" src="https://s3.amazonaws.com/codecademy-content/projects/red-eye-photography/p1.jpg" />
<div class="block">
<h4 class="card-title">{{event.events[0].name.text}}</h4>
<p class="card-text">{{event}}</p>
Go somewhere
</div>
</div>
</div>
</section>
<h1>{{test}}</h1>
My problem occurs when I am trying to loop over "events" array in the JSON file.
I have tried to write "$scope.events = data.events;" in Home controller, " ng-repeat="event in events.events"" or "ng-repeat="event in events[0]"" in html file. This breaks loop and nothing is shown, but if I use "ng-repeat="event in events"" and then variable {{event.events[0].name.text}} in the code later on, it all works fine. I don't understand why there is a problem. It should work fine from my previous experience.
If you declare in your controller
$scope.events = data.data.events;
and have such template:
<section class="container" ng-repeat="event in events">
<div class="col-sm-4">
<div class="card">
<img class="img-responsive" src="https://s3.amazonaws.com/codecademy-content/projects/red-eye-photography/p1.jpg" />
<div class="block">
<h4 class="card-title">{{event.name.text}}</h4>
<p class="card-text">{{event}}</p>
Go somewhere
</div>
</div>
</div>
</section>
it should work. See codepen here

Using handlebars to iterate over a complex object

I have a special array how can I itereate over it ?
It looks like:
{
"0.1.0": {
"pictures": {
"list": ""
},
"show": true,
"implemented ": false,
"percentageDoneVersion": 100,
"description": "Programmierung ...",
"tasks": {
"1":{
"percentageDone":10,
"description":"Text1..."
},
"2":{
"percentageDone":70,
"description":"Text2..."
},
"3":{
"percentageDone":10,
"description":"Text3..."
}
}
}
}
I tried different things, but they did not work out...
Thank you.
I am not fully clear on the requirements but as per provided information, looks like you are looking from something link this:
<script id="template" type="text/x-template">
<div class="row" style="">
<hr>
<div class="col-xs-12 col-lg-12">
<div class="panel-group">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title"><a data-toggle="collapse" data-parent="#versionHeading{{#index}}" href="#versionHeading{{#index}}">{{{body.project.versionHeading}}}</a></h4>
</div>
<div id="versionHeading{{#index}}" class="panel-collapse collapse in">
<div class="panel-body">
<p>{{{body.project.versionIntro}}}:</p>
{{#each body.project.versionContent}}
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title"><a data-toggle="collapse" data-parent="#mainVersion{{#index}}" href="#mainVersion{{#index}}">Version {{#key}}</a></h4>
</div>
<div id="mainVersion{{#index}}" class="panel-collapse collapse in">
<div class="panel-body">
<p>{{{this.description}}}</p>
<ul>
{{#each this.tasks}}
<li>{{#key}}.) {{{this.description}}} (progress ({{this.percentageDone}}% done)</li>
{{/each}}
</ul>
</div>
</div>
</div>
{{/each}}
</div>
</div>
</div>
</div>
</div>
</div>
</script>
Assuming that your provided json data is wrapped inside a body and project structure i.e.
{
"body": {
"project": {
"versionContent": {
....
}
}
}
}
Here is a working jsFiddle from your data and html. You can improve this as required. Version and Tasks both can grow dynamically. I recommend you to go through this simple Handlebars tutorial.

Ember Data isn't seeing my local store

Full Disclosure: I am new to Ember.
I have an app that I have started where when the user clicks on the next button, they create an instance of the customer model and that model is saved to local storage. On the next page, I want both the first and last name to pre-populate the text inputs. I have tried to follow the intro video but I have run into a problem. It appears that I am creating the object and then storing it successfully in local storage, but when the user transitions to the next page, the model can't be found. Here is my code:
HTML:
<script type="text/x-handlebars">
<div class="navbar navbar-inverse navbar-fixed-top">
<div id="nobox" class="navbar-inner">
<div class="container">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
</div>
</div>
</div>
<div class="container">
{{outlet}}
<footer>
</footer>
</div>
</body>
</script>
<script type="text/x-handlebars" data-template-name="index">
<div class="container main-container" id="main">
<div class="navbar">
<div class="navbar-inner">
<!--<div class="progress-bar-label-div">
Progress:
</div>
<div class="progress-bar-div">
<div class="progress progress-striped">
<div class="bar" style="width:60%;"></div>
</div>
</div>-->
<div class="btn-group pull-right">
<a class="btn btn-primary" id="captcha" {{action 'create'}}>
Next
</a>
</div>
</div>
</div>
<div id="messages">
</div>
<div class="row top">
<div class="pull-left" >
<h3 class="purple">To start the process, please fill out the captcha below</h3>
</div>
<div class="pull-right">
</div>
</div>
<div class="well">
<div class="row">
<div class="pull-left questions">
</div>
</div>
</div>
</div>
<hr>
</script>
<script type="text/x-handlebars" data-template-name="customer">
<div class="container main-container" id="main">
<div class="navbar">
<div class="navbar-inner">
<div class="btn-group pull-right">
{{#linkTo 'wsnum' action="create" classNames="btn btn-primary"}}Next{{/linkTo}}
</div>
</div>
</div>
<div id="messages">
</div>
<div class="row top">
<div class="pull-left">
<h3>Customer Information</h3>
</div>
<div class="pull-right">
</div>
</div>
<div class="row top">
<div class="pull-left">
<span class="red">*</span> = Denotes required field
</div>
<div class="pull-right form-inputs input-text">
</div>
</div>
<br>
<div class="row-b">
<div class="control-group">
<label class="control-label" for="inputfname">First Name<span class="red">*</span>:</label>
<div class="controls">
{{view Ember.TextField valueBinding='model.first'}}
</div>
</div>
</div>
<div class="row-a">
<div class="control-group">
<label class="control-label" for="inputlname">Last Name<span class="red">*</span>:</label>
<div class="controls">
{{view Ember.TextField valueBinding='model.last'}}
</div>
</div>
</div>
</div>
<input type="hidden" name="prev" value="">
<hr>
</script>
<script type="text/x-handlebars" data-template-name="wsnum">
<div class="container main-container" id="main">
<div class="navbar">
<div class="navbar-inner">
<!--<div class="progress-bar-label-div">
Progress:
</div>
<div class="progress-bar-div">
<div class="progress progress-striped">
<div class="bar" style="width:60%;"></div>
</div>
</div>-->
<div class="btn-group pull-right">
<!--<a class="btn" href="">
Prev
</a>
<a class="btn btn-primary" id="captcha">
Next
</a>-->
{{#linkTo 'customer' classNames="btn btn-primary"}}Prev{{/linkTo}}
</div>
</div>
</div>
<div id="messages">
</div>
<div class="row top">
<div class="pull-left" >
<h3>Choose the Number of Workstations or Point of Sale Accessories only</h3>
</div>
<div class="pull-right">
</div>
</div>
<div class="well">
<div class="row">
<div class="pull-left additional-questions">
How many workstations will you need?
</div>
<div class="pull-right input-text-well">
</div>
</div>
</div>
<div class="well">
<div class="row">
<div class="pull-left additional-questions">
Request Point of Sale Accessories only
</div>
<div class="pull-right radio-wsnum">
<label class="checkbox inline radio-new-pos">
<input type="checkbox" id="posonly1" name="posonly1" value="pos"> POS only
</label>
</div>
</div>
</div>
</div>
<hr>
</script>
<script type="text/x-handlebars" data-template-name="overview">
</script>
<script type="text/x-handlebars" data-template-name="new">
</script>
<script type="text/x-handlebars" data-template-name="existing">
</script>
And my app.js:
App = Ember.Application.create();
App.store = DS.Store.create({
revision: 12,
adapter: DS.LSAdapter.extend()
});
App.Router.map(function() {
// put your routes here
this.route("customer", { path: "/customer" });
this.route("wsnum", {path: "/wsnum"});
});
App.IndexRoute = Ember.Route.extend({
});
App.IndexController = Ember.Controller.extend({
create: function(){
var customer = App.Customer.createRecord({
first:"ron",
last:"testing"
});
console.log('Before the save');
customer.save();
console.log(customer.get('first'));
this.transitionToRoute('customer');
}
});
App.CustomerRoute = Ember.Route.extend({
model: function() {
var customer = App.Customer.find();
console.log(customer.get('first'));
return customer;
}
});
App.WsnumRoute = Ember.Route.extend({
});
var attr = DS.attr;
App.Customer = DS.Model.extend({
first: attr('string'),
last: attr('string')
});
Here is a working example. Any ideas?
In App.CustomerRoute.model(), this line:
var customer = App.Customer.find();
sets the customer variable is being set to result of find(). find() returns an array of all customer records. So when you call get('first') on the array it is undefined, since the array of customers does not have a property first.
Also, the route
this.route("customer", { path: "/customer" });
should probably be:
this.route("customer", { path: "/customer/:customer_id" });
since it seems to be for displaying one customer not a list of them.
With that change, CustomerRoute is not really needed at all. So app looks like:
App = Ember.Application.create();
App.store = DS.Store.create({
revision: 12,
adapter: DS.LSAdapter.extend()
});
App.Router.map(function() {
this.route("customer", { path: "/customer/:customer_id" });
this.route("wsnum", {path: "/wsnum"});
});
App.IndexController = Ember.Controller.extend({
create: function(){
var controller = this;
var customer = App.Customer.createRecord({
first:"ron",
last:"harmon"
});
customer.save().then(function() {
controller.transitionTo('customer', customer);
});
}
});
var attr = DS.attr;
App.Customer = DS.Model.extend({
first: attr('string'),
last: attr('string')
});
Working example here: http://jsbin.com/itogeh/1/edit

Categories