OfficeDev/office-js

The onMessageRecipientsChangedHandler gets triggered multiple times in the react component

Closed this issue · 9 comments

  1. We are developing office web Addin for outlook using event based (Smart Alert) .The Addin is generated using office yo generator Task Pane add-in using the React framework.
  2. We are getting the recipient data [ to/cc/bcc ] using Office.context.mailbox.item and we are rendering the same recipients onto the taskpane.
  3. We have two scenarios where :
    - When user adds any recipients in To/Cc/Bcc sections and clicks on send, user will be blocked by a smart alert [Soft Block]
    and once the user clicks on send button of smart alert the taskpane gets opened with the recipients.
    - Second is with taskpane open if user enters any recipients in To/Cc/Bcc sections then that recipients will get painted on to
    taskpane in real time. This scenario is breaking because we have added onMessageRecipientsChangedHandler in the react
    component as well due to which the launch event gets triggered multiple times.

Your Environment

  • Platform : Office on the web
  • Host : Outlook [OWA] & New Outlook [Desktop]
  • Office version number : Version 2311 Build 16.0.17029.20140
  • Operating System : Windows
  • Browser : Chrome & Edge

Expected behavior

Even in the component when user tries to add any recipients the onMessageRecipientsChangedHandler should get called only once.

Current behavior

  1. When ever we have any useEffect Hooks the component re-renders due to which the onMessageRecipientsChangedHandler gets called odd number of times every time in OWA and the same code behaves differently in New Outlook where the onMessageRecipientsChangedHandler gets triggered randomly multiple times [ no pattern as such noticed].
  2. Because the onMessageRecipientsChangedHandler gets triggered multiple times we are facing performance issues.

Steps to reproduce

  1. Add the OnMessageRecipientsChangeHandler and OnMessageSend events in the launchevents.js file.
  2. Add OnMessageRecipientsChangeHandler in the react component as well as shown below. In the below react component the OnMessageRecipientsChangeHandler is getting called multiple times when ever the component re renders.
import React, { useEffect, useState } from "react";

const Taskpane = () => {
  const [recipients, setRecipients] = useState([]);
  const [recipientCount, setRecipientCount] = useState(0);

  useEffect(() => {
    setRecipientCount(recipients.length);
  }, [recipients]);

  Office.onReady(() => {
    console.log("On ready");
    const itemType = Office.context.mailbox.item.itemType;

    if (itemType === Office.MailboxEnums.ItemType.Message) {
      Office.context.mailbox.item.addHandlerAsync(
        Office.EventType.RecipientsChanged,
        onMessageRecipientsChangedHandler1
      );
    } else if (itemType === Office.MailboxEnums.ItemType.Appointment) {
      Office.context.mailbox.item.addHandlerAsync(
        Office.EventType.RecipientsChanged,
        onAppointmentAttendeesChangedHandler1
      );
    }
  });

  function onMessageRecipientsChangedHandler1(event) {
    console.log("onMessageRecipientsChangedHandler1");

    if (event.changedRecipientFields.to) {
      console.log("To Section");
      Office.context.mailbox.item.to.getAsync(function (asyncResult) {
        if (asyncResult.status === Office.AsyncResultStatus.Succeeded) {
          let fetchrecipients = asyncResult.value;
          console.log("To", fetchrecipients);
          setRecipients(fetchrecipients);
          console.log("Recipients Email:", fetchrecipients);
        } else {
          console.error(
            "Error fetching required attendees:",
            asyncResult.error
          );
        }
      });
    }
  }

  function onAppointmentAttendeesChangedHandler1(event) {
    console.log("onAppointmentAttendeesChangedHandler1");

    if (event.changedRecipientFields.requiredAttendees) {
      console.log("requiredAttendees Section");
      Office.context.mailbox.item.requiredAttendees.getAsync(function (
        asyncResult
      ) {
        if (asyncResult.status === Office.AsyncResultStatus.Succeeded) {
          let fetchrecipients = asyncResult.value;
          console.log("requiredAttendees", fetchrecipients);
          setRecipients(fetchrecipients);
        } else {
          console.error(
            "Error fetching required attendees:",
            asyncResult.error
          );
        }
      });
    }
  }

  return (
    <>
      <div>
        <p>Total recipients: {recipientCount}</p>
        {recipients.map((recipient) => {
          return <li>{recipient.emailAddress}</li>;
        })}
      </div>
    </>
  );
};

export default Taskpane;

Context

  1. We are majorly facing performance issue.
  2. And in New Outlook the onMessageRecipientsChangedHandler gets triggered multiple times and sometimes goes to infinite loops.

Useful logs

  1. OWA ScreenShot:
image
  1. New Outlook:
image

Thank you for taking the time to report an issue. Our triage team will respond to you in less than 72 hours. Normally, response time is <10 hours Monday through Friday. We do not triage on weekends.

Thanks for reporting this issue @RaveendraReshma . a couple of clarification questions.

  1. are you seeing the event been triggered even with no recipients added/removed manually? if this happens this is a bug in our side. it should not. Is this in the New Outlook? or in OWA? or both?
  2. Do you have the same handlers for both the AutoLaunch Event and the one you added in the taskpane?

what you are experiencing is to a degree by design. You are getting the autoLaunch event and the non-AutoLaunch event triggered. Your add-in should be able to handle this condition with state management , you can use sessionData to store state across the autoLaunch event and the task pane. Not sure if you have tried this.

@JuaneloJuanelo

1) are you seeing the event been triggered even with no recipients added/removed manually? if this happens this is a bug in our side. it should not. Is this in the New Outlook? or in OWA? or both?

  • Event gets triggered multiple times only when we remove/add recipients manually from To/Cc/Bcc Sections.
  • This is happening only in case of the event handlers that i have added in the taskpane component. That to this is happening only when i have use effect hooks in the component.
  • This is happening both in OWA and New Outlook.

2) Do you have the same handlers for both the AutoLaunch Event and the one you added in the taskpane?

  • Yes i have same event handlers for both the AutoLaunch Event and the one I added in the taskpane.

  • I have just changed the name of the event handlers.

  • Below is how i have the events in the launchevents.js file.[AutoLaunch Event]

function onAppointmentAttendeesChangedHandler(event) {}

function onMessageRecipientsChangedHandler(event) {
if (event.changedRecipientFields.to) {
      Office.context.mailbox.item.to.getAsync(function (asyncResult) {
        if (asyncResult.status === Office.AsyncResultStatus.Succeeded) {
          let fetchrecipients = asyncResult.value;
          console.log("To", fetchrecipients);
          console.log("Recipients Email:", fetchrecipients);
        } else {
          console.error(
            "Error fetching To recipients:",
            asyncResult.error
          );
        }
      });
    }
}

Office.actions.associate(
    "onMessageRecipientsChangedHandler",
    onMessageRecipientsChangedHandler
);
Office.actions.associate(
    "onAppointmentAttendeesChangedHandler",
    onAppointmentAttendeesChangedHandler
);
  • In the taskpane component i have just changed the name as below
function onMessageRecipientsChangedHandler1(event) {}
function onAppointmentAttendeesChangedHandler1(event) {}

thanks @RaveendraReshma , further questions.

  1. when you say "Multiple times" this is really 2 times, right? (because you have the auto-launch and non-Auto_launch subscriptions. is that correct? [this is by design, btw.. and with state management you should be able to deal with this.]
  2. i am not sure exactly what you are trying to do here, but having this handler blank for the taskpane means that the event is irrelevant in the taskpane? or you need both events to do the same ?

thanks!

@JuaneloJuanelo

1) When you say "Multiple times" this is really 2 times, right? (because you have the auto-launch and non-Auto_launch subscriptions. is that correct? [this is by design, btw.. and with state management you should be able to deal with this.]

  • No multiple times in the sense there is pattern that I have noticed in OWA. With the taskpane open when ever I add or remove recipeints the non-Auto_launch event gets triggered odd number of times [ 1, 3, 5, 7, 9....]. And this number keeps on increasing.
  • In New Outlook the events gets triggered multiple times and goes to infinite loops.

2) i am not sure exactly what you are trying to do here, but having this handler blank for the taskpane means that the event is irrelevant in the taskpane? or you need both events to do the same ?

  • I have attached the launchevents and the taskpane component file.
  • Yes I need both auto-launch and non-Auto_launch events.
  • In both the auto-launch and non-Auto_launch events i am fetching the recipeints.
  • In the AutoLaunch events I am fetching the recipients and storing it in local Storage.
    Recip.zip

@RaveendraReshma i am not able to repro 1) above. i wonder if you can share specific repro steps to check this or a manifest we can use to repro it?

@JuaneloJuanelo

The above 1) issue got resolved by adding onReady within a useEffect Hook.
Now the event triggers only two times [ one autolaunch and one non auto launch ]

useEffect(() => {
    Office.onReady(() => {
      console.log("On ready non AutoLaunchEvent");
      const itemType = Office.context.mailbox.item.itemType;

      if (itemType === Office.MailboxEnums.ItemType.Message) {
        Office.context.mailbox.item.addHandlerAsync(
          Office.EventType.RecipientsChanged,
          onMessageRecipientsChangedHandler1
        );
      } else if (itemType === Office.MailboxEnums.ItemType.Appointment) {
        Office.context.mailbox.item.addHandlerAsync(
          Office.EventType.RecipientsChanged,
          onAppointmentAttendeesChangedHandler1
        );
      }
    });
  }, []);

@RaveendraReshma Thanks for updating us that the issue is resolved.

This issue has been automatically marked as stale because it is marked as needing author feedback but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment. Thank you for your interest in Office Add-ins!

This issue has been closed due to inactivity. Please comment if you still need assistance and we'll re-open the issue.