0

I'm having trouble updating data being passed around in my application. Passing down the data to my components is easy, but updating the attribute(data) has been difficult for me.

My Original Expectation:

all the attribute values I'm passing down through my components are all connected to the the original workItems array inside my top-level"taskboard" component, so modifying something down the chain, I assume, should update the value at the top of the chain, but it looks like this isn't the case.

Questions:

  • is there some aspect of immutability involved in the aura framework? For example, is the attribute data the child component have copies from the values up the chain?
  • is there some re-rendering that I should be doing or refetching of data instead? I was expecting to see my UI updates after doing component.set(..) in my taskModal component.

    User flow:

    • I click "add Task button" on workItem component, which fires "AA_addTaskEvent" on a work item. I also package a work item object in the event.

    • The topmost component "AA_taskboard"(not .app), listens for the "addTaskEvent", adds the work item object as a value to it's 'work' attrivute & invokes "handleAddTaskEvent" which unhides "AA_taskModal" component & passes the work item object to the modal component.

    • Inside my modal I have verified after seeing the object I recieved, that I do have access to the specific work item I clicked. However, when modify & update the work item, I don't see any changes happening, it's as if the item is immutable.

    Afer reading this other SO response (link) about passing across components, I have a hunch that it has to do with the values I'm passing down my components.

AA_taskboardApp.app

<aura:application extends="force:slds">
  <c:AA_taskboard />
</aura:application>

AA_taskboard.cmp

<aura:component controller="AA_taskboardController">

  <aura:attribute name="workItems" type="agf__ADM_Work__c[]" description="all of the items for the current sprint. Data will in after initializing this component" />
  <aura:attribute name="work" type="agf__ADM_Work__c" description="a work item (object) that will get passed up from the 'addTaskEvent' fired from a workItem component. This work item object will later be passed to the task modal so it has access to the work item that was clicked"/>

  <aura:handler name="init" action="{!c.doInit}" value="{!this}" description="fetch the work item data when this component initializes" />
  <aura:handler name="addTaskEvent" event="c:AA_addTaskEvent" action="{!c.handleAddTaskEvent}" description="handles the event fired from the workItem component"/>

  <c:AA_workList workItems="{!v.workItems}" />
  <c:AA_taskModal aura:id="task-modal" work="{!v.work}" />


</aura:component>

AA_taskModal.cmp

<aura:component>

  <aura:attribute name="work" type="agf__ADM_Work__c" description="a work item that's passed to the modal. Flow: addNewTask event from workItem component fires and sends the work item(object) to the taskboard.cmp, then the taskboard passes it to this modal" />
  <aura:registerEvent name="saveNewTaskEvent" type="c:AA_saveNewTaskEvent" description="An event that fire after the user had entered a new task name and hit save. This event sends up the taskname to the taskboard component." />

  <div class="task-modal hide" aura:id="task-modal">
    <ui:inputText aura:id="task-input" class="slds-input" />

    <button onclick="{!c.cancelNewTask}">Cancel</button>
    <button onclick="{!c.saveNewTask}">Save</button>

  </div>

</aura:component>

AA_taskModalController.js

({
  saveNewTask: function(component, event, helper) {
    var taskInput = component.find('task-input');
    var newTaskName = taskInput.get("v.value"); // 'NEWTASK'

    var work = component.get("v.work");
    work.agf__Tasks__r.push({
      agf__Subject__c: newTaskName
    });
    work.agf__Subject__c = "rename work";                 
    component.set('v.work', work); //doesn't update anything. Am I updating a copy & not a reference to the work item in my taskboard.cmp's array?
  },


  //Get & hide modal  if user hits cancel on modal
  cancelNewTask: function(component, event, helper) {
    var taskModal = component.find('task-modal');
    $A.util.addClass(taskModal, "hide")
  }
})

AA_workList.cmp

  <aura:component>
    <aura:attribute name="workItems" type="agf__ADM_Work__c[]" />

      <ol class="work-list">
        <aura:iteration items="{!v.workItems}" var="workItem">
          <li class="work-item-container">
              <c:AA_workItem work="{!workItem}" tasks="{!workItem.agf__Tasks__r}"/>
          </li>
        </aura:iteration>
      </ol>

  </aura:component>

AA_workItem.cmp

<aura:component>

  <aura:attribute name="work" type="agf__ADM_Work__c" />
  <aura:attribute name="tasks" type="agf__ADM_Task__c[]" />  
  <aura:attribute name="showTasks" type="Boolean" default="false" />
  <aura:registerEvent name="addTaskEvent" type="c:AA_addTaskEvent" description="an application event fired when user clicks add task button on this work item. Task modal component at the root(taskboard.cmp) listens for this event." />
  <aura:handler event="c:AA_updateTaskEvent" action="{!c.updateTask}" description="Handler for application event fired from the task modal after the user had entered a new task name and hit save. This event sends up the taskname to a workItem component that's listening for it" ./>

  <div class="work-item">
    <header>{!v.work.agf__Subject__c}</header>
    <button onclick="{!c.addTask}">Add Task</button>
    <!-- Tasks -->
    <ol class="work-tasks">
      <aura:iteration items="{!v.work.agf__Tasks__r}" var="taskItem">
        <li class="task-item">
          <c:AA_taskItem task="{!taskItem}" />
        </li>
      </aura:iteration>
    </ol>
  </div>
  <div>

</aura:component>
  • Just a guess, I assume it could be because you are getting current instance of the work component attribute and setting it back to work attribute, have you tried creating a new object var newwork = [] and newwork.push(work); and then set component.set('v.work', newwork ); – Rao Nov 8 '16 at 0:01
  • Look similar to the issue discussed here – Praveen Nov 8 '16 at 8:29
  • Doing the following inside my taskModalController updated my tasks array, but didn't change my UI to add the new task item in the list. It looks like I need to trigger an event in my modal, passing the new task item, to my taskboard & update my work items there. var tasks = work.agf__Tasks__r; tasks.push({agf__Subject__c: newTaskName}); component.set('v.work.agf__Tasks_r', tasks); updated my tasks array, but didn't update my list in the UI – cacoder Nov 8 '16 at 17:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.