Material-ui: Avatar onError callback with src update is no longer updating avatar image

Created on 31 Jan 2020  路  11Comments  路  Source: mui-org/material-ui

When the Avatar component fails to load an image, in some cases the developer may want catch this event and show another image instead, the solution advised on #5257 and #11128 are no longer working as intended, as of latest version 4.9

  • [x] The issue is present in the latest release.
  • [x] I have searched the issues of this repository and believe that this is not a duplicate.

Current Behavior 馃槸

onError callback is still called but it seems like the setting of src has no effect, an inspection of the live element shows that there is no element at all after the error occurs

Expected Behavior 馃

onError callback is called and the setting of the src field updates the element making it display the new image of the new value

Steps to Reproduce 馃暪

https://codesandbox.io/s/zealous-leavitt-kgb9o

I have noticed that the behaviors starts occurring from version 4.7.2 forward

I have provided a second Avatar directly displaying the fallback image, to show that it's not the fallback's image src problem

Context 馃敠

I'm trying to establish a fallback pipeline in cases which the Avatar component fails to fetch the originally provided image src,

Your Environment 馃寧

| Tech | Version |
| ----------- | ------- |
| Material-UI | v4.9.0 |
| React | 16.12.0 |

Avatar question

Most helpful comment

@UltimateForm Here is one way to handle the issue, use fallback children:

      <Avatar src="https://www.wronglink.com/trash.png">
        <img
          className="MuiAvatar-img"
          src="https://cdn.materialdistrict.com/wp-content/uploads/2018/09/materialdistrict-com-favicon.png"
        />
      </Avatar>

An approach that mutates the DOM node without "informing" React about is questionable, it's asking for issues later down the road. We would recommend using a state to change the src when an error is detected

All 11 comments

This is an effect of #16161 most likely, but is it an intended or unintended side effect?

I think there's another problem too, that I started to notice more as i began implementing a state solution on my side: the onError is not called sometimes when errors occur, this is happening on the sandbox too but I initially thought it was just the console acting up

yup, just confirmed with this sandbox https://codesandbox.io/s/flamboyant-frog-yf49e , i have an and an side by side, both provided with erratic urls, and i observed that - after a many refreshes - only always calls the onError function

But this feels like a completely different issue

Note: the original issue persists since even when the callback is called on Avatar's side, the avatar graphic is still not updated

@UltimateForm Here is one way to handle the issue, use fallback children:

      <Avatar src="https://www.wronglink.com/trash.png">
        <img
          className="MuiAvatar-img"
          src="https://cdn.materialdistrict.com/wp-content/uploads/2018/09/materialdistrict-com-favicon.png"
        />
      </Avatar>

An approach that mutates the DOM node without "informing" React about is questionable, it's asking for issues later down the road. We would recommend using a state to change the src when an error is detected

@oliviertassinari there is still the issue that onError callback is only called sometimes.... so

using a state to change the src when an error is detected

would only work half the time

there is still the issue that onError callback is only called sometimes

@UltimateForm Is this an issue with React?

@oliviertassinari I don't think it's an issue with react since it's only happening with the Avatar component

https://codesandbox.io/s/flamboyant-frog-yf49e <- if you keep refreshing you can see here that img's onError callback is always called while Avatar's onError callback is just called sometimes, it could be intentional... which would be weird...

also, @oliviertassinari , I just implemented the solution you suggested and it's not quite optimal since it hides the letter on the avatar if both images throw an error

according to documentation if I provide children the Avatar will not fallback to the "the first letter of the alt text"

Fallbacks
If there is an error loading the avatar image, the component falls back to an alternative in the following order:

the provided children
the first letter of tha alt text
a generic avatar icon

(also there's a typo in there ahah)

I feel like the ideal solution here would be a onError callback followed by a setState, if you want I can create a new issue about the onError callback

@UltimateForm Cool, so we are good. You can use the onError callback and change the state.

Feel free to send a pull request to solve the typo :).

@oliviertassinari again the children approach is still not as optimal because I still want the letter fallback if both images fail, but for now I can just do this:

      <Avatar src="https://www.wronglink.com/trash.png">
        <Avatar
          src="https://cdn.materialdistrict.com/wp-content/uploads/2018/09/materialdistrict-com-favicon.png"
        >
             M
        </Avatar>
      </Avatar>

Thanks for the help!

(and i've done the PR)

I don't understand

Was this page helpful?
0 / 5 - 0 ratings

Related issues

reflog picture reflog  路  3Comments

FranBran picture FranBran  路  3Comments

mb-copart picture mb-copart  路  3Comments

iamzhouyi picture iamzhouyi  路  3Comments

anthony-dandrea picture anthony-dandrea  路  3Comments