Converting image bytes to base64 in React Native: A step-by-step guide

When requesting the product image from the backend, I want to show it to the user.

The issue is: the API response contains a PNG image if the product has an image, but returns a (204 NO Content) if the product does not have an image. So, I need to display a default image in that case.

After some research, I found the defaultSource prop for the <Image> component, which works fine on IOS but not on Android.

<Image
          defaultSource={{ uri: productDefaultImage }}
          source={{
            uri: env.apiUrl.concat(env.productImageById.replace(":productId", price.id.toString())).concat("?thumbnail=true"), headers: { Authorization: `Bearer ${token}`}
          }}
          resizeMode="contain"
          style={{ width: 100, height: 70 }}
          onLoadEnd={() => setImageLoading(false)}
        />

Here are some of the returned data from the API:

�PNG


IHDRww^��   pHYs��IDATx^����wu���9u��=9g͌rH ���1x�1��YG���kÚ�/�ؘl�,!��F��g:��ʹ�����ww�y�����6�����tW=ϭ�{���sϑ�;v���#`G���;v���#`G���;v���#`G���;v���#` ...

Is there a way to display the default image on Android as well?

Answer №1

let xyz = picture.encodeAsString("base64");

Answer №2

By moving your URI into a piece of state, you can utilize the onError callback to assign the URI to your default URL (check out this demo):

import React, { useState } from 'react';
import { Text, View, StyleSheet, Image } from 'react-native';
import Constants from 'expo-constants';
import { TextInput } from 'react-native-paper';

const defaultSrc =
  'https://media.istockphoto.com/id/1271122894/photo/planet-earth-from-the-space-at-night.jpg?s=612x612&w=0&k=20&c=PU-_OdSqlMs47X3FKQQBEruZcI38QJ4XLPpYi9b7dJ4=';

export default function App() {
  const [url, setUrl] = useState('');
  const [text, setText] = useState('');
  const [hasImageErr,setHasImgErr] = useState(false)
  return (
    <View style={styles.container}>
      <TextInput
        label="Paste a url"
        value={text}
        onChangeText={setText}
        right={
          <TextInput.Icon
            icon="check"
            color="green"
            onPress={() => setUrl(text)}
          />
        }
      />
      {hasImageErr &&<Text style={styles.errText}>Error loading image</Text>}
      <Image
        style={styles.image}
        source={{ uri: url }}
        onError={() => {
          if(!url)
            return
          console.log('Error loading image. Switching to default image')
          setUrl(defaultSrc)
          setHasImgErr(true)
        }}
        onLoad={()=>{
          // called when image loading succeeds
          if(defaultSrc !== url)
            setHasImgErr(false)
        }}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
  image:{
    margin:5,
    width:100,
    height:100,
    alignSelf:'center'
  },
  errText:{
    color:'red',
    alignSelf:'center'
    }
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can I automatically refresh the page when switching languages using @shopify/react-i18n?

Even though I am using MobX to store the state of the language and changing the locale in the I18nContext.Provider, the translations on the page do not change when switching languages. This is my custom hook: import {useI18n} from "@shopify/react-i18n"; i ...

Error: The dataProvider function toJSON is not recognized

import restProvider from 'ra-data-simple-rest' const dataProvider= process.env.REACT_APP_API+'/api/link' <Admin dataProvider={restProvider(dataProvider) }> <Resource name='endpoint' options={{label:'MyLab ...

Identifying when a fetch operation has completed in vue.js can be accomplished by utilizing promises

Currently, I am facing a dilemma in my Vue.js application. I am making an API call within the created() hook, but there are certain tasks that I need to trigger only after the API call has been completed. The issue is that this API call usually takes aroun ...

Error occurred while trying to launch React application with "npm start" command due to ELIFECYCLE issue

Encountering an error while attempting to launch my React app. events.js:174 throw er; // Unhandled 'error' event ^ Error: spawn powershell.exe ENOENT at Process.ChildProcess._handle.onexit (internal/child_process.js:240:19) ...

Send submitted form field arrays to the database

I am currently developing a sewing management app that includes an order page where users can place multiple orders. However, all orders need to be invoiced with one reference code. On the first page, I collect basic details such as pricing, and on the nex ...

Mastering Inter-Composable Communication in Vue 3: A Guide

Composables in Vue documentation demonstrate how small composition functions can be used for organizing code by composing the app. Discover More About Extracting Composables for Code Organization "Extracted composables act as component-scoped servi ...

CSS media query to target specific viewport width

In my JavaScript code, I am dynamically creating a meta viewport. I set the value of this viewport to be 980px using the following script: var customViewPort=document.createElement('meta'); customViewPort.id="viewport"; customViewPort.name = "vie ...

find all the possible combinations of elements from multiple arrays

I have a set of N arrays that contain objects with the same keys. arr[ {values:val1,names:someName},   {values:val2,names:otherName}, ] arr2[   {values:valx,names:someNamex}, {values:valy,names:otherNamey}, ] My goal is to combine all possible c ...

The React context is currently yielding an undefined value

I am puzzled by this issue. I have double-checked to ensure that the states value is not undefined, and it isn't. However, I am unable to pinpoint where I may be making a mistake. Here is my authContext.js file: const initialState = { isAuthorized: ...

Tips for creating useEffect logic to automatically close the menu when the URL changes

How do I use a useEffect statement in Next.js 14 to close the megamenu when the current URL changes? useEffect(() => { const handleScroll = () => { if (window.scrollY > 0) { setScrolling(true); } else { setScrolling(false); ...

The Google Maps API allows all markers to be connected to a single infowindow

I've been grappling with this issue for some time now, but I just can't seem to find a solution! I'm retrieving data from a database in Laravel using Ajax and then attempting to display infowindows for each marker on Google Maps. The markers ...

The ReactJS button produces component output when activated with props

I have a situation where I am working with 2 buttons that, when clicked, display different components based on the button type. The code is designed in such a way that it can handle any number of components and corresponding buttons. When a button is act ...

Sequential execution not functioning properly in NodeJS Async series

Here is the code snippet I am working with: var async = require('async'); var rest = require('restler'); async.series([ function(callback){ rest.get('https://api.twitter.com/1.1/statuses/mentions_timeli ...

Customizing the appearance of individual columns in the Material-UI DataGrid

My goal is to center an IconButton within a DataGrid table, all of which are MUI components. Despite reading the documentation and trying various methods, I haven't achieved the desired result yet. In my latest attempt, I implemented the following: G ...

When iterating over objects in JavaScript, the loop may return undefined, while using Lodash's map

After encountering an issue with a JavaScript loop where the value was returning as null upon completion, I decided to try using lodash for the same purpose and it successfully returned the result. This is what I attempted: JavaScript: const jsRows = Ob ...

The usage of the bootstrapTable() function creates a gap below the displayed table information

Currently, I am working on incorporating a table into my webpage that will load data from an API. After some research, I found a Bootstrap table library to assist with this task. However, I have encountered an issue with setting the table height dynamicall ...

Add numerous submit buttons within a form. Upon clicking on a button, the form should be submitted to a specific URL using AJAX

I have a form with two submit buttons: one labeled as "SUBMIT" and the other as "SCHEDULE NEXT ROUND". When a user clicks on the "SUBMIT" button, the form values should be stored in the database and redirect to the view page. If they click on the "SCHEDULE ...

The toggle checkbox feature in AngularJS seems to be malfunctioning as it is constantly stuck in the "off"

I am trying to display the on and off status based on a scope variable. However, it always shows as off, even when it should be on or checked. In the console window, it shows as checked, but on the toggle button it displays as off Here is the HTML code: ...

Vue.js Interval Functionality Malfunctioning

I'm brand new to Vuejs and I'm attempting to set an interval for a function, but unfortunately it's not working as expected. Instead, I am encountering the following error: Uncaught TypeError: Cannot read property 'unshift' of u ...

Learn how to implement React Redux using React Hooks and correctly use the useDispatch function while ensuring type-checking

I'm curious about the implementation of Redux with Typescript in a React App. I have set up type-checking on Reducer and I'm using useTypedSelector from react-redux. The only issue I have is with loose type-checking inside the case statements of ...