AngularJs - ngRepeat Delete a particular line in View - javascript

I have a simple rendering of 3 items with their particular ids glued with there name fields. I want to show a particular message whenever I delete that line only with the button to follow. When I am doing it, I have problem in passing the id for delete for that particular line only, and all the n rows (here 3) are getting deleted.
HTML :
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<div>
<p ng-repeat="x in List" ng-show="!deleted">{{x.name}}<button ng-click="del(x.id)">Delete</button></p>
<p ng-show="deleted">This line has been deleted.</p>
</div>
<script>
//module declaration
var app = angular.module('myApp',[]);
//Controller declaration
app.controller('myCtrl',function($scope){
$scope.deleted = false;
$scope.List = [{"name":"Peter Martin","id":"1"},{"name":"Lita Schedan","id":"2"},{"name":"Jenni Markints","id":"3"}];
$scope.del = function(id){
//for this id -> only
$scope.deleted = true;
}
});
</script>
</body>
</html>
This means, if I put delete button of line 2. The first and second rows must come with the delete button, but in the middle line the message "This line has been deleted" must show.

You should basically show the row which has deleted flag false by using angular filter. For that you need to make sure you List object show have deleted prop to false on initial load. Then on click pass whole row object to del method. And for showing error message you could use $timeout that will show an message for half second
Markup
<div>
<p ng-repeat="x in List | filter : {deleted: false}">
{{x.name}}
<button ng-click="del(x)">Delete</button>
</p>
<p ng-show="deleted">Line with id {{deletedId}} has been deleted.</p>
</div>
And on click of element make delete flag to true
Controller
//Controller declaration
app.controller('myCtrl',function($scope, $timeout){
$scope.deleted = false;
$scope.List = [{"name":"Peter Martin","id":"1"},{"name":"Lita Schedan","id":"2"},{"name":"Jenni Markints","id":"3"}];
angular.forEach($scope.List, function(ele){
ele.deleted = false;
})
$scope.del = function(x){ //passed object
x.deleted = true;
//for showing message
$scope.deleted = true;
$scope.deletedId = x.id;
$timeout(function(){
$scope.deleted = false;
$scope.deletedId = undefined;
}, 500)
}
});
If you really wanted to remove element from the array you could use .slice() method by passing $index to it

Related

How to pass value into ng-if after ng-click?

Purpose
I am trying to get admin and customer show in different stages, admin can post the data after clicking the toggleShowDiv(), which allows customer to see the data.
Question
How to pass !isAdmin() into ng-if? Currently, I am only getting isAdmin as default.
Is able to post it into table TD by TD (row by row)? not sure, I am writing the correct code here.
My thought
Can I use ng-if to each single TD = isAdmin() or !isAdmin, and control by a click function?
$scope.showDiv = isAdmin();
$scope.toggleShowDiv = function (auction) {
var title = 'text.......';
var text = 'are you sure?';
ConfirmModal(title, text, function () {
$scope.showDiv = !isAdmin() ;
});
};
HTML
<div ng-if="showDiv">
<tbody class="auction-group" ng-repeat="a in foos">
<td ng-if="isAdmin()">
<input type="checkbox" ng-click="toggleShowDiv()" />
</td>
</div>
Update
isAdmin() is just a function that passed from the backend.
function isAdmin() {
return !!($aScope.currentUser && $aScope.currentUser.isAdministrator);
}
Please note: the question is not about the isAdmin() function, it works fine. What I want to do is to use a click function to show and hide the table row.
Have a look at this. Here you have 2 users online at the same time, dude1 (admin) and dude2 (non admin). You can toggle the display from the admin side for the non admin side by having a call to the back end that continuously checks if the display is valid or not. For putting a toggle on the table rows you need to just add the ng-if to the <tr> elements.
var app = angular.module('app', []);
app.controller("controller", function($scope) {
$scope.dude1 = {admin: true, name: [{name: 'A+', country:'India', publish: true}, {name: 'A', country:'Unknown', publish: true}]};
$scope.dude2 = {admin: false, name: [{name: 'A+', country:'India', publish: true}, {name: 'A', country:'Unknown', publish: true}]};
$scope.toggler = (index) => {
$scope.dude1.name[index].publish = !$scope.dude1.name[index].publish;
};
$scope.names = (dude) => {
return dude.name;
};
setInterval(() => {
/**
* Any backed function to get and repopulate the data.
* Update the value of publish from the server. I'm just using
* the other guys data. But you should fetch it from the server.
*/
$scope.dude2 = valfromServer();
// console.log($scope.dude2, $scope.dude1);
}, 2000);
var valfromServer = () => {
return {
admin: false,
name: $scope.dude1.name
};
};
$scope.publish = (dude, index) => {
return dude.admin || dude.name[index].publish;
};
$scope.isAdmin = (dude) => {
return dude.admin;
};
});
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#1.6.0" data-semver="1.6.0" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.js"></script>
</head>
<body ng-app="app" ng-controller="controller">
<span>Admin Panel</span>
<div>
<table style="width:40%">
<tr ng-repeat="x in names(dude1)" ng-if="publish(dude1, $index)">
<td>{{ x.name }}</td>
<td>{{ x.country }}</td>
<td>{{ $index }}</td>
<td><button ng-click="toggler($index)" ng-if="isAdmin(dude1)">Publish</button></td>
</tr>
</table>
</div>
<hr>
<span>Non admin panel</span>
<div>
<table style="width:40%">
<tr ng-repeat="x in names(dude2)" ng-if="publish(dude2, $index)">
<td>{{ x.name }}</td>
<td>{{ x.country }}</td>
<td>{{ $index }}</td>
<td><button ng-click="toggler($index)" ng-if="isAdmin(dude2)">Publish</button></td>
</tr>
</table>
</div>
</body>
</html>
<div ng-if="showDiv == true || isAdmin == true">
<tbody class="auction-group" ng-repeat="a in foos">
<td ng-if="isAdmin == true">
<input type="checkbox" ng-click="toggleShowDiv()" />
</td>
</div>
JS code Let say first any one who enters will be customer
$scope.showDiv = false;
$scope.isAdmin = false;
now when response comes form backend check the response and change the value of $scope.isAdmin accordingly.
if(response == admin){
$scope.isAdmin= true;
}else{
$scope.isAdmin = false;
}
now in onclick checkbox function
$scope.toggleShowDiv = function (auction) {
var title = 'text.......';
var text = 'are you sure?';
ConfirmModal(title, text, function () {
if($scope.showDiv == false){
$scope.showDiv = true;
}else{
$scope.showDiv = false;
}
});
};
Well I think that you should use some var that change according if the user click like $scope.showTable = true /false. But not complety sure about your real need.
I am confused on your question -
I will suggest few points, i hope it will help you -
ng-if is a inbuilt directive. You can use it on any DOM element. You can control it by using attribute or function, only need to pass Boolean attribute to this directive. Eg:
ng-if="showHideAttribute" or ng-if="functionNameWhichReturnBoolean()"
Scope - if you are clicking on button/checkbox/ng-click applied element is available in the same scope of applied ng-if directive then no problem. Otherwise you need to use service or observers (on/emit/broadcast) or rootScope then only it will work.
I hope you are receiving isAdmin = true/false from backend in your function. So, i am thinking this is the problem of scope.
Instead of ng-if="showDiv" use something link ng-if="obj.showDiv"
In the controller define $scope.obj = {};
The issue is ng-if creates its own scope, so always pass data as an object because objects in JS are passed by reference.
You can do this
ng-if = "isAdmin == false"
You're really confusing me, but if I understood correctly, it is something like this you want?
First things first, your HTML is truely horrible, parts of tables in divs? Don't do that...
Secondly, don't hack kabout with the isAdmin to toggle things.
isAdmin should only be used to check if a user is an admin.
You can however create another variable that instantiates to the same value, and use that one to toggle stuff.
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
this.content = 'This is some unpublished content, only the admin can view, unless you\'ve now gone and publish it.';
this.isPublished = false;
this.isAdmin = false;
});
/* Put your css in here */
textarea,
label,
button {
display: block;
margin: 15px 15px 0 0;
}
button {
display: inline-block;
}
<script data-require="angular.js#1.5.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
<div ng-app="plunker">
<div ng-controller="MainCtrl as $ctrl" ng-init="$ctrl.isAdmin=false">
<article>
<section class="content">
<section ng-if="$ctrl.isAdmin || $ctrl.isPublished">{{ $ctrl.content }}</section>
<section ng-if="!$ctrl.isAdmin && !$ctrl.isPublished"><pre>-- no published content found --</pre></section>
</section>
<section class="admin-only" ng-if="$ctrl.isAdmin">
<label><input type="checkbox" ng-model="$ctrl.isPublished"> publish article</label>
</section>
</article>
<hr />
<label><input type="checkbox" ng-model="$ctrl.isAdmin"> is admin</label>
</div>
</div>
edit:
You're still confusing me, but does this come closer to what you want / need?
What i understand is, "When admin trigger some action i.e. ng-click, user should be able to see that data/changes."
If this is the case, consider following:
I'm damn sure that this is not going to happen on the same machine.
Admin will be using the application on his machine from where it'll
do some action i.e. ng-click will gets fired and some data will gets
changed on server.
Now there will be (n) number of users using the application from
their machines. How they will get to know about the change which admin has made?
In such scenario, when there is changes on server and
client(browser) should be aware of that we make use of socket.io,
which listens to events from server and refreshes itself when there
is some changes on server state or we can say, when admin has
triggered some action i.e. ng-click.
Let me know, if you have any queries.
Thanks

Cascading selects AngularJS filter not display data in second time

Considering the code below:
<html ng-app="app">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.3/angular.min.js"></script>
</head>
<body ng-controller="appCtrl">
<div class="filters">
<div>
Color: <select id="color" ng-model="colorfilter" ng-options="car.color as car.color for car in cars | unique:'color'" ng-change="changeColor()">
</select>
Model: <select id="model" ng-disabled="!colorfilter" ng-model="modelfilter" ng-options="car.model as car.model for car in cars | filter:{color:colorfilter} | unique:'model'" ng-change="changeModel()">
</select>
</div>
</div>
<div class="list">
<p class="car" ng-repeat="car in cars | filter:colorfilter | filter:modelfilter">{{car.make}} :: {{car.model}} | {{car.color}}</p>
</div>
</body>
</html>
And the controller.js:
angular.module('app', [])
.filter('unique', function() {
return function(input, key) {
var unique = {};
var uniqueList = [];
for(var i = 0; i < input.length; i++){
if(typeof unique[input[i][key]] == "undefined"){
unique[input[i][key]] = "";
uniqueList.push(input[i]);
}
}
return uniqueList;
};
})
.controller('appCtrl', function($scope) {
// define list of cars
$scope.cars = [
{make:"Dodge", color:"Blue", model:"Dakota"},
{make:"Chevy", color:"Black", model:"Aveo"},
{make:"Honda", color:"Black", model:"Accord"},
{make:"Toyota", color:"Red", model:"Corolla"}
//... other lines
];
// initialize filter object
$scope.filter = {};
});
The list of cars is displayed complete below the select fields. When I filter at the first time, the first select normally filters both the list of cars (considering the selected color) and the second select data (only models that have the selected color). And the second select also filters the list of cars considering the selected model. That sounds perfect!
However, when I try to perform a new filter, when I choose another color, it does not display any records in the list of cars, but it usually works by filtering the data of the second select. By choosing one of the models available in the second select, the list is displayed, exactly the combination of the two selections (such as an AND of the selects).
It seems that only the list data that is currently being viewed on the screen are considered for the first select, needing to wait for the second select to display the result. But my intend is to display the results to each filter, always searching for the complete list of items.
My full code on Codepen.
I think this may be what you're looking for. Based on your ng-disabled logic, I figured you want the user to always go in the order of selecting color then model.
https://codepen.io/Cameron64/pen/YZbrqW?editors=1010
To maintain this order I set the color dropdown to reset when the model dropdown is selected from. Additionally I grouped the filter into one object so that it isn't so verbose when passed to the repeater
$scope.changeColor = function() {
$scope.filter.model = undefined;
$scope.filter.color = $scope.filter.color || undefined;
}
Update:
You need to set the null value for modelFilter to reset the filter.
Your code is working fine however when you select a value in second dropdown, you are setting the value to modelfilter which is causing the issue.
Try to insert an empty dropdown option in both the dropdowns so that when you select first dropdown it will reset to default state and modelFilter won't apply.
Working Demo:
CodePen

Update unrelated field when clicking Angular checkbox

I have a list of checkboxes for people, and I need to trigger an event that will display information about each person selected in another area of the view. I am getting the event to run in my controller and updating the array of staff information. However, the view is not updated with this information. I think this is probably some kind of scope issue, but cannot find anything that works. I have tried adding a $watch, my code seems to think that is already running. I have also tried adding a directive, but nothing in there seems to make this work any better. I am very, very new to Angular and do not know where to look for help on this.
My view includes the following:
<div data-ng-controller="staffController as staffCtrl" id="providerList" class="scrollDiv">
<fieldset>
<p data-ng-repeat="person in staffCtrl.persons">
<input type="checkbox" name="selectedPersons" value="{{ physician.StaffNumber }}" data-ng-model="person.isSelected"
data-ng-checked="isSelected(person.StaffNumber)" data-ng-change="staffCtrl.toggleSelection(person.StaffNumber)" />
{{ person.LastName }}, {{ person.FirstName }}<br />
</p>
</fieldset>
</div>
<div data-ng-controller="staffController as staffCtrl">
# of items: <span data-ng-bind="staffCtrl.infoList.length"></span>
<ul>
<li data-ng-repeat="info in staffCtrl.infoList">
<span data-ng-bind="info.staffInfoItem1"></span>
</li>
</ul>
</div>
My controller includes the following:
function getStaffInfo(staffId, date) {
staffService.getStaffInfoById(staffId)
.then(success)
.catch(failed);
function success(data) {
if (!self.infoList.length > 0) {
self.infoList = [];
}
var staffItems = { staffId: staffNumber, info: data };
self.infoList.push(staffItems);
}
function failed(err) {
self.errorMessage = err;
}
}
self.toggleSelection = function toggleSelection(staffId) {
var idx = self.selectedStaff.indexOf(staffId);
// is currently selected
if (idx >= 0) {
self.selectedStaff.splice(idx, 1);
removeInfoForStaff(staffId);
} else {
self.selectedStaff.push(staffId);
getStaffInfo(staffId);
}
};
Thanks in advance!!
In the code you posted, there are two main problems. One in the template, and one in the controller logic.
Your template is the following :
<div data-ng-controller="staffController as staffCtrl" id="providerList" class="scrollDiv">
<!-- ngRepeat where you select the persons -->
</div>
<div data-ng-controller="staffController as staffCtrl">
<!-- ngRepeat where you show persons info -->
</div>
Here, you declared twice the controller, therefore, you have two instances of it. When you select the persons, you are storing the info in the data structures of the first instance. But the part of the view that displays the infos is working with other instances of the data structures, that are undefined or empty. The controller should be declared on a parent element of the two divs.
The second mistake is the following :
if (!self.infoList.length > 0) {
self.infoList = [];
}
You probably meant :
if (!self.infoList) {
self.infoList = [];
}
which could be rewrited as :
self.infoList = self.infoList || [];

How to programmatically select ng-option value?

I have a view that is filled with dropdownlists to filter a report. I also have a view of saved filters that are displayed as links. When a user clicks on their saved filters, I want the appropriate values of the dropdownlists to be selected. The drop downs are being populated properly. On the saved filter link there is an ng-click that will call a function that iterates through the collection of saved filter values and automatically selects the correct one. I cannot figure out how to programmatically set the selected option. Any help is much appreciated!
<select uid="locSelect"
class="span12"
ng-model="reportDetail.selectedLoc"
ng-options="loc.dbid as loc.serviceName for loc in reportDetail.locList | orderBy:'name'">
<option uid="unselectedLocOption" value="">-- Select One --</option>
</select>
Here is the list of saved filters:
<div class=" well fixed-search" style="overflow-x: hidden;overflow-y: auto;">
<div class="well-header">
Saved Filters
</div>
<div ng-if="!hasSavedFilters">
<span>No saved filters</span>
</div>
<ul ng-if="hasSavedFilters" class="nav nav-list dashboard-list">
<li ng-repeat="filter in reportDetail.savedFilters">
<a uid="savedFilter" href="" ng-click="reportDetail.loadSavedFilters(filter.filters)">
<span ng-bind="filter.title"></span>
</a>
</li>
</ul>
And here is my controller
(function(){
'use strict';
var ReportDetailController = function(ReportsService, $scope){
var _locList = {};
var _hospitalStatusList = {};
var _providerStatusList = {};
var _savedFilters = [];
var _sourceTypeList = {};
var _dateRangeList = {};
var _init = function(){
ReportsService.getCurrentReportSavedFilters().then(function(data){
$scope.reportDetail.savedFilters =data;
$scope.hasSavedFilters = ReportsService.hasSavedFilters();
});
ReportsService.getLOCListForDDL().then(function(data){
$scope.reportDetail.locList = data;
//$scope.reportDetail.selectedLoc = $scope.reportDetail.locList[0];
});
ReportsService.getSelectListData()
.then(function(data){
$scope.reportDetail.sourceTypeList = data.CONNECTION_TARGET_STATUS;
$scope.reportDetail.hospitalStatusList = data.CONNECTION_SOURCE_STATUS;
});
ReportsService.getDateRangesForDDL()
.then(function(data){
$scope.reportDetail.dateRangeList = data;
});
$scope.reportDetail.providerStatusList = ReportsService.getProviderStatusForDDL();
};
var _loadSavedFilters = function(filters){
for(var i = 0, l = $scope.reportDetail.locList.length; i<l; i++){
if($scope.reportDetail.locList[i].serviceName == filters.levelOfCare){
$scope.reportDetail.selectedLoc = $scope.reportDetail.locList[i];
console.log($scope.reportDetail.selectedLoc);
}
}
}
var _isActive = function(filter){
for(var i = 0, l = $scope.reportDetail.savedFilters.length; i<l; i++){
if(filter.title == $scope.reportDetail.savedFilters[i].title){
return true;
}
return false;
}
}
var _generateReport = function(){
return ReportsService.generateReport();
};
$scope.reportDetail = {
init: _init,
selectedLoc: null,
isActive: _isActive,
locList: _locList,
selectedHospitalStatus: 'NOTIFIED',
hospitalStatusList: _hospitalStatusList,
selectedProviderStatus: 'NEW',
providerStatusList: _providerStatusList,
selectedSourceType: 'CONNECTED',
sourceTypeList: _sourceTypeList,
selectedDateRange: '',
dateRangeList: _dateRangeList,
savedFilters: _savedFilters,
loadSavedFilters: _loadSavedFilters,
generateReport: _generateReport
};
$scope.reportDetail.init();
};
app.controller('ReportDetailController', ['ReportsService', '$scope', ReportDetailController]);
})();
You just need to set the ng-model to whatever it should be, so in this case you would set reportDetail.selectedLoc to whatever loc.dbid it should be.
For example: http://jsfiddle.net/uWLua/1/
Note: Make sure they have the same type, so in your example make sure they are either both integers, or both strings, it will not know they are the same if you have one as 5073 and one as "5073"
I updated the fiddle to show that the string and number do not do the same thing.
The ng-model and the expression feeding ng-options -must- match in order for Angular to compare values and see what option is 'selected'. Just as 'dave' indicated.
Due to time constraints I ended up going a different route. I created an event bus of sorts in my service layer and subscribe to the even in my controller, updating the model, and used ng-repeat with ng-selected.
I'm still interested to understand why this was not working with ng-options. The model and ng-options types matched, and everything appeared to be wired up correctly. When I have more time i'll re-address the original issue. Thanks for all who responded!
You need custom directive, or something similar to this two approaches
<div ng-controller="MyCtrl">
<h1>Approach 1</h1>
<span ng-repeat="val in dbs">
<input type="checkbox" ng-model="val.checked">{{val.name}}
</span>
<hr/>
<h1>Approach 1</h1>
<select multiple>
<option ng-repeat="val in dbs" name="val.name" value="val.name" ng-selected="val.checked">{{val.name}}</option>
</select>
<h4>Source (note scope changes)</h4>
{{dbs}}
</div>
also you can use ng-change to do some complex ops
If I understand, in summary, you have a select filled with a list, and you want to programmatically set one of those to be selected, type it as the default right?
If so, you can easily solve this with ng-options, just associate your controller instance with scope and assign the position of the list you want to the model of select, for example:
Select HTML
<select ng-model="vm.aluno_id" name="aluno_id" ng-options="aluno.nome for aluno in alunos">
Controller
app.controller("auxiliarController", function( $scope){
//instancia controller;(Controller instance;)
var vm = this;
$scope.vm = vm;
//carregando lista no scope, que serĂ¡ utilizado pelo angular no select
//Loading list in scope, which will be used by angular in select
$scope.alunos = [{id: 1, nome: "aa"}, {id: 2, nome: "bb"}];
//setando item default no select
$scope.vm.aluno_id = $scope.alunos[0];
});
I hope I have helped

AngularFire removes Firebase locations

I'm trying to create a collaborative story-making app, using Angular and Firebase. Follow this link to get an idea of where I'm headed so far. You click on the "plus" icon to show a textarea, and add to the parts that are already there. I'm sure there are many ways to improve what I've coded so far, but my specific problem right now relates to switching between stories.
I have another Firebase reference with two stories, and each of the stories has different parts. To create a way to switch between stories I tried the following:
html:
<!doctype html>
<html lang="en" ng-app = "StoryApp">
<head>
<script src="https://cdn.firebase.com/v0/firebase.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angularFire/0.1.0/angularfire.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<div class="wrapper" ng-controller="WrapperCtrl">
<div class="nav">
<a ng-repeat="story in storyList" ng-click="switchStory(story.location)" href="#" id="{{story.identity}}" style="margin-left:0.5em;">{{story.title}} Button</a>
</div>
</br>
<div class="insideWrapper">
<span class="item" id="{{part.number}}" ng-repeat="part in parts" ng-controller="ItemCtrl">{{part.text}}
<span ng-click="show=!show" style="margin-left:0.25em;color:blue;cursor:pointer;">+(Add Part Here)</span>
<form ng-show="show" ng-submit="addItem()">
<textarea ng-model="itemText" placeholder="Your story"></textarea>
<br>
<button type="submit" class="submit-button" value="submit" ng-click="show=!show">add</button>
<button ng-click="show=!show">cancel</button>
</form>
</span>
</div>
</div>
</body>
javascript:
var gApp = angular.module('StoryApp', ['firebase']);
function WrapperCtrl($scope, angularFire){
var urlStories = 'https://allstory.firebaseio.com/stories';
$scope.storyList = angularFire(urlStories, $scope, 'storyList', {});
function getStory(url){
var urlParts = url;
$scope.parts = angularFire(urlParts, $scope, 'parts', []);
}
$scope.switchStory = function(location){
getStory(location);
};
getStory('https://allstory.firebaseio.com/stories/story1/parts');
}
function ItemCtrl($scope){
$('.wrapper').on('click', '.submit-button', function(event) {
var idNum = function() {
return event.target.parentNode.parentNode.id;
};
$scope.addItem = function(){
$scope.parts.splice(Number(idNum())+1, 0, {text:$scope.itemText, number:Number(idNum())+1});
$scope.itemText = '';
reNumber();
};
function reNumber() {
var i = Number(idNum())+2, len=$scope.parts.length;
for (; i < len; i++) {
$scope.parts[i].number = i;
}
}
});
}
The above code isn't working for me. When "Story 1" or "Story 2" are clicked in the view I expected that the view would change to reflect the change in Firebase reference location (url). However, rather than the appropriate parts of the respective story appearing, nothing appears, and the parts locations (e.g. https://allstory.firebaseio.com/stories/story1/parts) for both stories are removed from my Firebase reference. My problem may be similar to this one.
I need the parts for "Story 1" or "Story 2" to appear when clicked. What can I change in my code to make this work? Should I try an entirely different approach to switching between stories?
AngularFire retrieves data from Firebase asynchronously and returns a promise, not the actual data itself. Therefore, you have a bug in your code where you're assigning the promise to the scope variable but using it before the promise has been resolved.
I would fetch both stories first before allowing the user to switch between them. For example:
function WrapperCtrl($scope, angularFire) {
$scope.showStories = false;
var urlStories = 'https://allstory.firebaseio.com/stories';
angularFire(urlStories, $scope, 'storyList', {}).then(function() {
$scope.showStories = true;
});
$scope.switchStory = function(location) {
// var name = manipulate location to extract story number or name, like "story1".
$scope.parts = $scope.storyList[name]["parts"];
}
}

Categories