AngularJS --> Select requires to clicks to visually change - javascript

I'm using the following HTML and am having issues when a user selects from the dropdown box. The issue is that when you click the first time, you can see the variable change through a console log, but visually the item remains blank. If I select the item again, it will then visually show.
Here's my HTML>
<div class="section">
<select ng-model="companyInfo" ng-change='getCompany(companyInfo)'
ng-options="company.name for company in list">
</select><br>
</div>
I have a feeling its a real rookie mistake, but I can't figure it out!
Any help would be greatly appreciated.
EDIT --
Thanks for the quick replies! Should have given getCompaniesList
$scope.getCompany = function(company) {
console.log("companyInfo passed", company);
internalClientService.getCompany(company.name)
.then(function(companyRecord){
console.log("returning record from getCompany service", companyRecord);
$scope.currentCompany = companyRecord[0].name;
$scope.currentCompanyId = companyRecord[0].companyid;
getFarmList(companyRecord[0].farms);
});
};
var getFarmList = function(farmIdArray){
$scope.farmsList = [];
internalClientService.getFarms(farmIdArray)
.then(function(farmNames){
console.log('the farmNames returning', farmNames);
for (var i = 0; i<farmNames.length; i++){
$scope.farmsList.push(farmNames[i].name);
}
});
};
The internalCLientService is a simple HTTP request.
What do you think?
Thanks,
B

Related

One div input element will not pull information from sessionStorage using javascript

enter image description hereI am trying to develop a ticketing tool for work and its a template site to make taking notes for helpdesk more easily and when something is an escalation and you click the button for escalation template. When the escalation template loads I want it to pull information from session storage to avoid copying and pasting notes already taken.
This is how I am storing the information in session storage and I checked via Chrome browser that information is being stored in the session storage.
if(callInbound)
{
sessionStorage.setItem("ACTIVITYTYPE", document.form1.activity.value);
sessionStorage.setItem("CONTACTNAME", document.form1.name.value);
sessionStorage.setItem("VIPSTATUS", document.form1.vip.value);
sessionStorage.setItem("CONTACTNUMBER", document.form1.phone.value);
sessionStorage.setItem("CALLERLOCATION", document.form1.location.value);
sessionStorage.setItem("ISSUEDESCRIPTION",document.form1.issueDescription.value); <--PROBLEM ITEM
sessionStorage.setItem("ERRORMESSAGE", document.form1.errorMessage.value);
sessionStorage.setItem("TROUBLESHOOTING", document.form1.troubleshooting.value);
sessionStorage.setItem("KNOWLEDGEUSED", document.form1.knowledgeUsed.value);
sessionStorage.setItem("SEARCHTERMSTRIED", document.form1.searchtermsTried.value);
sessionStorage.setItem("SCREENSHOTSATTACHED", document.form1.screenshotsAttached.value);
sessionStorage.setItem("SURVEYOFFERED", document.form1.surveyOffered.value);
sessionStorage.setItem("SURVEYTAKEN", document.form1.surveyTaken.value);
}
This is the page where the information is being loaded and all but the one identified as problem is being populated into the template.
<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=windows-1252"><title>DSI Call Outbound</title>
<script type="text/javascript" src="DSI.js"></script>
<script language="JavaScript" type="text/javascript">
window.addEventListener('load', ()=>{
let callInboundCallDropped = sessionStorage.getItem("CALLINBOUNDCALLDROPPED");
let callOutboundCallDropped = sessionStorage.getItem("CALLOUTBOUNDCALLDROPPED")
let additionalIssue = sessionStorage.getItem("ADDITIONALISSUE");
let voicemailCallBack = sessionStorage.getItem("VOICEMAILRECEIVED");
if (callInboundCallDropped == "true")
{
document.form1.issueDescription.value = sessionStorage.getItem("ISSUEDESCRIPTION");<--Problem Item
document.form1.name.value = sessionStorage.getItem("CONTACTNAME");
document.form1.phone.value = sessionStorage.getItem("CONTACTNUMBER");
document.form1.errorMessage.value = sessionStorage.getItem("ERRORMESSAGE");
}
else if (callOutboundCallDropped == "true")
{
document.form1.name.value = sessionStorage.getItem("CONTACTNAME");
document.form1.phone.value = sessionStorage.getItem("CONTACTNUMBER");
document.form1.issueDescription.value = sessionStorage.getItem("ISSUEDESCRIPTION");<--Problem item
document.form1.errorMessage.value = sessionStorage.getItem("ERRORSMESSAGE");
}
else if(additionalIssue == "true")
{
document.form1.activity.value = "***ADDITIONAL ISSUE***";
document.form1.name.value = sessionStorage.getItem("CONTACTNAME");
document.form1.phone.value = sessionStorage.getItem("CONTACTNUMBER");
}
else if(voicemailCallBack == "true");
{
document.form1.name.value = sessionStorage.getItem("CONTACTNAME");
document.form1.phone.value = sessionStorage.getItem("CONTACTNUMBER");
document.form1.issueDescription.value = sessionStorage.getItem("VOICEMAILSUBJECT");
document.form1.errorMessage.value = sessionStorage.getItem("ERRORMESSAGE");
}
//sessionStorage.clear();
})
</script>
All other items load properly from session storage when the page is loaded. I confirmed that the information is in session storage via the application section in the inspection section of Chrome browser and by adding alert("ISSUEDESCRIPTION"); below the problem item line and it works as expected.
I have tried the following:
// Store your value from one page sessionStorage.setItem("values",
"input_text");
// Retrieve the value from another page var value =
sessionStorage.getItem("values");
//replacing the line with and assigning and id to the div element in the html document.getElementById("issueDescription").value = sessionStorage.getItem("ISSUEDESCRIPTION");
This is the problem element:
<div class="w3-row w3-section">
<div class="w3-col" style="width:50px"><i class="w3-xxlarge w3-animate-zoom"></i></div>
<div class="w3-rest">
<p>Issue Description</p>
<input class="w3-input w3-border" name="issueDescription" type="text" placeholder="[Issue Description Here]">
</div>
</div>
This is an element on the same page that is correctly being filled with session storage information:
<div class="w3-row w3-section">
<div class="w3-col" style="width:50px"><i class="w3-xxlarge w3-animate-zoom"></i></div>
<div class="w3-rest">
<p>Phone Number Used</p>
<input class="w3-input w3-border" name="phone" type="text" placeholder="(xxx)xxx-xxxx">
</div>
</div>
please tell me if I'm just referencing something incorrectly like a typo although I've spent multiple hours doublechecking everything. Wish there were a troubleshooting/debugging feature in Visual Studio Code for this kind of stuff to step through it. If there is and I'm unaware please let me know.
Unsure of why this didn't work the first few times I tried it, but this time when I copied and pasted the elements name in the "documents.form1.issueDescription.value = sessionStorage.getItem("ISSUEDESCRIPTION");"
the issue was resolved, swear I did this on repeat late last night, must've been a spelling error.

Salesforce Lightning Component will not update records via Apex call, freezes

Issue overview: Currently coding a Lightning Component to update records on a custom object. However, every time I trigger the update (via a ui:button), the page freezes and I don't see any errors in the debugger or console. Cannot for the life of me figure out why it won't work.
Context: The component has a number of dropdowns that are populated with records (with the label being the record name). Selecting a new value in the dropdown and hitting "Update" calls the below apex to change a custom field (Status__c = 'Ready') on the new selected item, and then updates the records that occur before it (Status__c = 'Complete). I do all of my security and update checks in another function during init, so you won't see that here (I can post the full code if needed). Just trying to get the update to work.
I would be eternally grateful if someone could show me the error of my ways :]. Always been a huge fan of stackoverflow and looking forward to contributing now that I finally signed up. Thanks for your time everyone!
Apex:
#AuraEnabled
public static void updateMilestones(String deployId,Boolean prodChanged,String newProdMile) {
if( prodChanged == true && newProdMile != null ) {
try {
decimal newProdStepNum;
List <Milestone__c> newReadyProdMile = New List<Milestone__c>();
for(Milestone__c mil1:[SELECT id, Status__c, Step_Order__c FROM Milestone__c
WHERE Deployment__c = :deployID
AND id = :newProdMile LIMIT 1]){
mil1.Status__c = 'Ready';
newProdStepNum = mil1.Step_Order__c;
newReadyProdMile.add(mil1);
}
List <Milestone__c> prodMilesComplete = New List<Milestone__c>();
for(Milestone__c mil2:[SELECT id, Type__C, Status__c FROM Milestone__c
WHERE Deployment__c = :deployID
AND Step_Order__c < :newProdStepNum
AND Type__c = 'Production'
AND Status__c != 'Complete'
AND Status__c != 'Revised']){
mil2.Status__c = 'Complete';
prodMilesComplete.add(mil2);
}
update newReadyProdMile;
update prodMilesComplete;
}
catch (DmlException e) {
throw new AuraHandledException('Sorry, the update did not work this time. Refresh and try again please!');
}
}
}
Javascript:
updateMilestones : function(component, event, helper) {
// update milestones server-side
var action = component.get("c.updateMilestones");
action.setParams({
deployId : component.get("v.recordId"),
newProdMile : component.find("prod-mile-select").get("v.value"),
prodChanged : component.get("v.prodChanged")
});
// Add callback behavior for when response is received
action.setCallback(this, function(response) {
var state = response.getState();
if (component.isValid() && state === "SUCCESS") {
// re-run the init function to refresh the data in the component
helper.milesInit(component);
// refresh record detail
$A.get("e.force:refreshView").fire();
// set Update Changed Milestones button back to disabled
component.find("updateButton").set("v.disabled","true");
// show success notification
var toastEvent = $A.get("e.force:showToast");
toastEvent.setParams({
"title": "Success!",
"message": "Milestones have been updated successfully."
});
toastEvent.fire();
}
});
// Send action off to be executed
$A.enqueueAction(action);
}
Component:
<aura:component controller="auraMilestonesController_v2"
implements="force:appHostable,flexipage:availableForRecordHome,force:hasRecordId,force:lightningQuickAction">
<ltng:require scripts="{!$Resource.lodash}" afterScriptsLoaded="{!c.doInit}"/>
<aura:attribute name="recordId" type="String" />
<aura:attribute name="prodMiles" type="Milestone__c[]"/>
<aura:attribute name="prodChanged" type="Boolean" default="false"/>
<!-- FORM -->
<div class="slds-col slds-col--padded slds-p-top--large" id="theform">
<form class="slds-form--stacked">
<!-- UPDATE BUTTON -->
<div class="slds-form-element">
<ui:button aura:id="updateButton" label="Update Changed Milestones" press="{!c.updateMilestones}"
class="slds-button slds-button--brand slds-align--absolute-center" disabled="true"/>
</div>
<hr style="color: #005fb2;background-color: #005fb2;"/>
<!-- PRODUCTION -->
<div aura:id="prod-section">
<div class="slds-form-element">
<label class="slds-form-element__label" for="milestone">Production Milestone</label>
<div class="slds-form-element__control">
<div class="slds-select_container">
<ui:inputSelect aura:id="prod-mile-select" class="slds-select" change="{!c.prodChange}">
<option value="" >--Select One--</option>
<aura:iteration items="{!v.prodMiles}" var="m">
<aura:if isTrue="{!m.Status__c == 'Ready'}">
<option value="{!m.id}" selected="true">{!m.Name} ({!m.User_Name__c})</option>
</aura:if>
<aura:if isTrue="{!m.Status__c == 'Not Ready'}">
<option value="{!m.id}">{!m.Name} ({!m.User_Name__c})</option>
</aura:if>
</aura:iteration>
<option value="completeProdMile" id="completeProdMile">All Production Milestones Complete</option>
</ui:inputSelect>
</div>
</div>
</div>
<div class="slds-form-element">
<label class="slds-form-element__label" for="description">Description</label>
<div class="slds-textarea">
<aura:iteration items="{!v.prodMiles}" var="m">
<aura:if isTrue="{!m.Status__c == 'Ready'}">{!m.Description__c}</aura:if>
<!-- <aura:set attribute="else">All production milestones have been completed.</aura:set> -->
</aura:iteration>
</div>
<hr style="color: #005fb2;background-color: #005fb2;"/>
</div>
</div>
<!-- END PRODUCTION -->
</form>
</div>
<!-- / FORM -->
</aura:component>
I believe the issue is that you have fallen into the all too common trap of naming both a client side and a server side controller method the same (updateMilestones in this case). Try changing the name of either to make them unique and I expect that will get you running.
Yes, there is a bug on this and many of us have been making a very loud noise about getting it fixed!
Also we have a very active Salesforce specific Stack Exchange forum over here https://salesforce.stackexchange.com/ that will get more attention - especially if you tag your posts with lightning-components (e.g. I have my account configured to send me an email alert on every post tagged with lightning-components, locker-service, etc).
That might be javascript causing the error.As it's difficult to solve without knowing the error, I would suggest you debug the error.
Turn on debug mode.
a. From Setup, click Develop > Lightning Components.
b. Select the Enable Debug Mode checkbox.
c. Click Save.
In Chrome Developer Tools, check the "Pause on Caught Exceptions" checkbox in the Sources tab. This can often help finding the source of an issue. Other browsers may have similar options.
Add a debugger statement if you want to step through some code.
debugger;
This is useful when you have a rough idea where the problem might be happening.
debugger
https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/debug_intro.htm

How do I access images depends on notification type

I stored notificationType in back end json file, And in notifacation controller i have stored same notificationtype with name and images(which images it supposed to show depends on notification type) for to compare.
Now i would like to acces the images depends on notification type.
i had tried like this but its taking only 0th position images it is taking.
I got to know what my mistake is but i dont know how to do it can anyone help me...
my code is.
controller.js
$scope.typeofnotification =[{name:'offer', imges: './resources/remote.png'},
{name:'discount', imges:'./resources/mic.png'},
{name:'upgrades', imges:'./resources/play-icon.png'}];
/*var len = $scope.typeofnotification.length*/
$scope.setNotificationImage = function(){
var notificationImage;
for (var i = 0; i < $scope.typeofnotification.length; i++)
{
if($scope.notificationData[i].notificationType == $scope.typeofnotification[i].name)
{
return notificationImage = $scope.typeofnotification[i].imges;
}
}
};
notificationData[i].notificationType this line from backend
one.HTML
<div class="notifications" ng-repeat="item in notificationData">
<img id="notificationImages" yo-src="setNotificationImage()"/>
<div id="notificationdata" yo-attr="{html: 'item.desc'}"></div>
<div id="notificationdate" yo-attr="{html: 'item.date'}"></div>
</div>
In the ng-repeat directive notificationdata comes from backend
output what i am getting is, only 1st image oth position image i am getting for all notification.
but i want images depends on notification type.
as for above code, If notification type is add_content it needs to display remote.png and if type is 'discount' it needs to display mic.png and finaly if typeis upgrades it needs to display play-icon.png
plz check images below.
enter image description here
In your solution you only get same value because of when satisfied first condition return that image url not your item image url.
you need to check with repeated item instead of $scope.notificationData so need to pass item when call setNotificationImage function and check with this item.notificationType === $scope.typeofnotification[i].name
like:
HTML:
<div class="notifications" ng-repeat="item in notificationData">
<img id="notificationImages" yo-src="setNotificationImage(item)"/> //pass item
<div id="notificationdata" yo-attr="{html: 'item.desc'}"></div>
<div id="notificationdate" yo-attr="{html: 'item.date'}"></div>
</div>
Controller:
$scope.setNotificationImage = function(item){
for (var i = 0; i < $scope.typeofnotification.length; i++)
{
if(item.notificationType === $scope.typeofnotification[i].name)
{
return $scope.typeofnotification[i].imges;
}
}
};

Populate Cascading Dropdown using json with functional Search

This has been one of the most frustrating online searches-for-an-answer-or-solution EVER! And I still haven't found anything out there that can perform this basic task - with that being said, this IS a search facility that's used very often all over the net ... so it comes as a surprise as to why there aren't many (any) demos / scripts for sale that can do this.
I want to have a search facility on my website whereby the user can select a country > province > town (3 drop downs).
Obviously if the user selects the USA (for example), the next dropdown populates / updates the provinces (states) relevant to USA and so forth with the next drop down.
I see a lot of people using ASP.net and AngularJS to perform this funtion but I am using neither languages and don't want to use them.
This guy here has developed a great solution for people who'd like their results to dynamically load up as they select items in the dropdowns - however this isn't what I want.
The Javascript and Json approach is where I like to go.
Now this guy here made a great / simple solution for populating dropdowns (I am going to post the code for this script later on).
But with ALL of these demos and scripts online, they are ALL missing one thing - the SEARCH facility. It's great populating a dropdown to select correct items but that's half the job done and that's all it does.
I want the user to be able to click a SEARCH button AFTER the last item in a dropdown is selected and go to it's respective page (because isn't that what is supposed to be for? - Of course that also depends on the project at hand).
So lets take the code of the populated dropdown created by the guy in the second link:
HTML:
<head>
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<script src="js/jquery-1.8.1.min.js"></script>
<script src="js/outils.js"></script>
</head>
<body>
<div>
<select id="Marque">
<option value="0">Choix du marque</option>
<option value="bmw">bmw</option>
<option value="mercedes">mercedes</option>
<option value="audi">audi</option>
<option value="volswagen">volswagen</option>
</select>
<select id="Serie"></select>
</div>
</body>
Javascript:
jQuery().ready(function(){
var tabMarque=[];
$.getJSON('file.json', function(data) {
$.each(data, function(index, val) {
tabMarque[index]=val;
});
});
$('#Marque').change(function(event) {
$marque=$(this).val();
$htmlOption='<option value="0">Choix du serie</option>';
if($marque!=0)
{
$.each(tabMarque[$marque], function(key, value) {
$htmlOption+='<option
value="'+value[0]+'">'+value[1]+'</option>';
});
}
$('#Serie').html($htmlOption);
});
});
JSON:
{
"bmw":[
["1","serie 1"],
["2","serie 3"],
["3","serie 5"],
["4","serie 7"]
],
"mercedes":[
["6","class A"],
["7","class B"],
["8","class C"],
["9","class E"]
],
"audi":[
["10","a3"],
["11","a4"],
["12","a5"],
["13","a6"]
],
"volswagen":[
["14","polo"],
["15","golf"],
["16","cady"]
]
}
(Sorry, I'd like to put this on JSfiddle but there's json involved and I don't know where to put the json code).
So after the 3 dropdown boxes, I'd like to have a button saying "Go" or "Search" and once it's clicked it takes the user to the page of the last selected item.
EG (using the example code above - understand there's only 2 dropdowns in his code):
I select:
BMW
1 Series
... and then when I click "GO" - it take me to bmw-1-series.htm
How can this be done?
Surely one could add urls to the items in the json file eg:
"bmw":[
["1","serie 1","http://www.example.com/bmw-1-series.htm"],
["2","serie 3","http://www.example.com/bmw-2-series.htm"],
["3","serie 5","http://www.example.com/bmw-3-series.htm"],
["4","serie 7","http://www.example.com/bmw-4-series.htm"]
],
and then when you click "GO", it will take you to the respective url. Obviously this needs extra code I can imagine to be able to grab the url of the selected item and take the user to that page (something I wouldn't know how to do)?
Is there a better way to do this?
UPDATE TO MAKE THIS CLEARER:
Go to CSS TRICKS DEMO
This is what I want (to be able to populate the dropdowns - this is the only thing the demo does) however if the user wants to search for Coffee's ... they would click on BEVERAGES > then choose COFFEE and then I'd like them to be able to click a button (just below the 2 dropdowns) saying SEARCH ... which will take them to a page with all the coffees listed on
As you requested, I looked at the code and have corrected it. It can be found at:
http://plnkr.co/edit/RnCdfnrX0jy3RvmXjF56
Link-only answers are frowned upon in StackOverflow, so I will write a little more:
As I wrote in my original comment:
If you are generally following along with the video you posted, you
should be able to use that as a foundation. You can do one of two
things with your links, either maintain your own datastructure (even a
basic Object) to map between the value of the leaf node select items
and then navigation destination, or add them directly as a data
attribute when adding them to the menu. Then your button code can
lookup the URL in whichever place you put it. In his line 15 (in the
'marque' handler) you could have:
$htmlOption+='<option value="'+val[0]+'" data-theurl="'+val[2]+'"...'
if URL is in spot 2
Although C Fasolin took the code you pointed to and my advice and attempted to convert it to an answer, you are correct that the code provided in the answer has errors in it.
Since SO requires code for Plunkr links, I now also have to paste some code in here as well. This is the corrected JS code minus the silly number of alerts injected into the code (which I only bothered to comment out in the Plunkr, but removed here to be tidier). The HTML and JSON were fine and are also on the Plunkr. Note that the JSON data only contains URLs for the BMW examples so you will get a 404 when clicking "go" for other makes, ou marques, en français.
$(document).ready(function() {
var tabMarque = [];
$.getJSON('data.json', function(data) {
$.each(data, function(index, val) {
tabMarque[index] = val;
});
});
$('#Marque').change(function(event) {
var marque = $(this).val();
var htmlOption = '<option value="0">Choix du serie</option>';
if (marque !== '0') {
var itemsMarque = tabMarque[marque];
$.each(itemsMarque, function(key, value) {
htmlOption += '<option value="' + value[0] + '" data-href="' + value[2] + '">' + value[1] + '</option>';
});
}
$('#Serie').html(htmlOption);
});
$('#go').click(function() {
var selected = $('#Serie').find('option:selected');
var href = selected.data('href');
window.location = href;
});
});
Happy menuing!
this solution work for me:
JAVASCRIPT:
$(document).ready(function(){
var tabMarque=[];
$.getJSON('file.data.txt', function (data) {
alert(data);
$.each(data, function(index, val) {
tabMarque[index]=val;
});
});
$('#Marque').change(function(event) {
alert('Marque_change');
var marque=$(this).val();
alert(marque);
var htmlOption='<option value="0">Choix du serie</option>';
if(marque!="0")
{
var itemsMarque = tabMarque[marque];
alert(JSON.stringify(itemsMarque));
$.each(itemsMarque, function (key, value) {
//alert("k=" + key + " v=" + JSON.stringify(value));
htmlOption+='<option value="'+value[0]+'" data-href="'+value[2]+'">'+value[1]+'</option>';
});
}
$('#Serie').html(htmlOption);
});
$('#go').click(function () {
alert('go_click');
var selected = $('#Serie').find('option:selected');
var href = selected.data('href');
alert('goto:'+href);
});
});
HTML
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<script src="js/jquery-1.8.1.min.js"></script>
<script src="js/outils.js"></script>
</head>
<body>
<div>
<select id="Marque">
<option value="0">Choix du marque</option>
<option value="bmw">bmw</option>
<option value="mercedes">mercedes</option>
<option value="audi">audi</option>
<option value="volswagen">volswagen</option>
</select>
<select id="Serie"></select>
<input type="button" id="go" value="Go!" />
</div>
</body>
</html>
JSON:
{
"bmw":[
["1","serie 1","http://www.example.com/bmw-1-series.htm"],
["2","serie 3","http://www.example.com/bmw-2-series.htm"],
["3","serie 5","http://www.example.com/bmw-3-series.htm"],
["4","serie 7","http://www.example.com/bmw-4-series.htm"]
],
"mercedes":[
["6","class A"],
["7","class B"],
["8","class C"],
["9","class E"]
],
"audi":[
["10","a3"],
["11","a4"],
["12","a5"],
["13","a6"]
],
"volswagen":[
["14","polo"],
["15","golf"],
["16","cady"]
]
}

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