onUploadProgress doesn't work

I am following the React Native course and in part two of the course in the Networking section, I ran into an issue. I am not able to get the upload progress from the backend when uploading a new listing. The post method itself is working correctly. I hope anyone can help me with this.

This is my listings.js file:

import client from “./client”;

const endpoint = “/listings/”;

const getListings = () => client.get(endpoint);

const addListing = (listing) => {
const data = new FormData();
data.append(“title”, listing.title);
data.append(“price”, listing.price);
data.append(“categoryId”, listing.category.value);
data.append(“description”, listing.description);

listing.images.forEach((image, index) =>
data.append(“images”, {
name: “image” + index,
type: “image/jpeg”,
uri: image,
})
);

if (listing.location)
data.append(“location”, JSON.stringify(listing.location));

return client.post(endpoint, data, {
onUploadProgress: (progress) => console.log(progress),
});
};

export default {
addListing,
getListings,
};

1 Like

having the same issue…no Success yet

Having this same issue. Any solution?

Still not solution yet?

Hello all. Having the same issue. But looking at axios docs Request Config | Axios Docs

// `onUploadProgress` allows handling of progress events for uploads
  // browser only
  onUploadProgress: function (progressEvent) {
    // Do whatever you want with the native progress event
  },

It’s not supposed to work. onUploadProgress is for browsers only, so it make sense that it doesn’t work on react-native.

I think that feature is completely deprecated at the moment. Agree @Mosh ?

I have been debugging this issue the whole day and I was not able to fix it. It used to be working.
Does anyone have a fix for it ?

I’m having the same issue.

Is someone here already fix it?

Hey Msalimbene,
My issue I have that is showing up my progress as 0%, like if not progress at all, but I get the data on the feed tab.

any suggestions?

return client.post(endpoint, data, {
onUploadProgress: (ProgressEvent) => {
onUploadProgress(ProgressEvent.loaded / ProgressEvent.total);
},
});

Hello @luisdiego, I don’t think it has been fixed. It is a problem with the component that works only on react-web. You are using react-native right?

1 Like

Yes, this I am using react native, thanks for replying!

HERE’S THE SOLUTION 2024

Guys i faced the same issue and solved it but i forgot what i did. The bugs are related to deprecated packages or a tiny detail in this course. That tiny detail is usually the ‘flex’ style.

Check out the animation container inside the uploadScreen.js

  animation: {
    width: 150,
    flex: 1, //!!necessary!!
  },

Here’s my whole code about it:

listings.js file:

Click to inspect the code
import client from "./client";

const listingsEndpoint = "/listings";

const getListings = () => client.get(listingsEndpoint);

const postListings = (listing, onUploadProgress) => {
  const data = new FormData();

  data.append("title", listing.title);
  data.append("price", listing.price);
  data.append("categoryId", listing.category.value);
  data.append("description", listing.description);

  listing.images.forEach((image, index) =>
    data.append("images", {
      name: "image" + index,
      type: "image/jpeg",
      uri: image,
    })
  );

  if (listing.location)
    data.append("location", JSON.stringify(listing.location));

  console.log("Posted Data:", data);

  return client.post(listingsEndpoint, data, {
    headers: {
      "Content-Type": "multipart/form-data",
    },
    onUploadProgress: (progress) => {
      if (onUploadProgress) {
        onUploadProgress(progress.loaded / progress.total);
      }
    },
  });
};

export default {
  getListings,
  postListings,
};

ListingEditScreen.js file:

Click to inspect the code
import { StyleSheet } from "react-native";
import { React, useState } from "react";
import * as Yup from "yup";

import Screen from "../components/Screen";
import {
  AppForm,
  AppFormField,
  AppFormPicker,
  SubmitButton,
} from "../components/forms";
import CategoryPickerItem from "../components/CategoryPickerItem";
import FormImagePicker from "../components/forms/FormImagePicker";
import useLocation from "../hooks/useLocation";
import listingsApi from "../api/listings";
import UploadScreen from "./UploadScreen";

const validationSchema = Yup.object().shape({
  title: Yup.string().required().min(1).label("Title"),
  price: Yup.number().required().min(1).max(10000).label("Price"),
  description: Yup.string().label("Description"),
  category: Yup.object().required().nullable().label("Category"),
  images: Yup.array().min(1, "Please select at least one image."),
});

const categories = [
  {
    label: "Furniture",
    value: 1,
    icon: "floor-lamp",
    backgroundColor: "#fc5c65",
  },
  { label: "Cars", value: 2, icon: "car", backgroundColor: "#fd9644" },
  { label: "Cameras", value: 3, icon: "camera", backgroundColor: "#fed330" },
  { label: "Games", value: 4, icon: "cards", backgroundColor: "#26de81" },
  {
    label: "Clothing",
    value: 5,
    icon: "shoe-heel",
    backgroundColor: "#2bcbba",
  },
  { label: "Sports", value: 6, icon: "basketball", backgroundColor: "#45aaf2" },
  {
    label: "Movies & Music",
    value: 7,
    icon: "headphones",
    backgroundColor: "#4b7bec",
  },
  {
    label: "Books",
    value: 8,
    icon: "book-open-blank-variant",
    backgroundColor: "#884ab4",
  },
  {
    label: "Other",
    value: 9,
    icon: "page-layout-header",
    backgroundColor: "#5e6f81",
  },
];

export default function ListingEditScreen() {
  const location = useLocation();

  //TODO: DONE check out the source control for bugs!
  const [uploadProgress, setUploadProgress] = useState(0);
  const [uploadVisible, setUploadVisible] = useState(false);

  const handleSubmit = async (listing, { resetForm }) => {
    setUploadProgress(0);
    setUploadVisible(true);
    const result = await listingsApi.postListings(
      { ...listing, location }, //FIXME: FIXED include the location data later
      (uploadProgress) => setUploadProgress(uploadProgress)
    );

    if (!result.ok) {
      setUploadVisible(false);
      return alert("Couldn't save the listing"); //FIXME: STILL causing error while uploading too many images.
    }

    resetForm();
  };

  return (
    <Screen style={styles.container}>
      <UploadScreen //FIXME: FIXED(with flex:1) done.json not shown on screen fully
        onDone={() => {
          setUploadVisible(false);
        }}
        visible={uploadVisible}
        progress={uploadProgress}
      />
      <AppForm
        initialValues={{
          title: "",
          price: "", //It must be string
          description: "",
          category: null,
          images: [],
        }}
        onSubmit={handleSubmit}
        validationSchema={validationSchema}
      >
        <FormImagePicker
          name="images"
          //FIXME: FIXED image not shown on screen and can't delete!
        />
        <AppFormField
          maxLength={255}
          name="title"
          placeholder="Title"
          //FIXME: FIXED Not reseting
        />
        <AppFormField
          containerWidth="30%"
          keyboardType="numeric"
          maxLength={8} //TODO: max 9999.99 increase the value later
          name="price"
          placeholder="Price"
          //FIXME: FIXED Not reseting
        />
        <AppFormPicker
          numColumns={3}
          containerWidth="55%"
          items={categories}
          name="category"
          PickerItemComponent={CategoryPickerItem}
          placeholder="Category"
        />
        <AppFormField
          maxLength={255}
          multiline
          name="description"
          numberOfLines={2}
          placeholder="Description"
          //FIXME: FIXED Not reseting
        />
        <SubmitButton title="Post" />
      </AppForm>
    </Screen>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 10,
  },
});

UploadScreen.js file:

Click to inspect the code
import { View, StyleSheet, Modal } from "react-native";
import React from "react";
import * as Progress from "react-native-progress";
import LottieView from "lottie-react-native";

import colors from "../config/colors";

export default function UploadScreen({
  onDone,
  progress = 0,
  visible = false,
}) {
  return (
    <Modal visible={visible}>
      <View style={styles.container}>
        {progress < 1 ? (
          <Progress.Bar
            color={colors.primary}
            progress={progress}
            width={200}
          />
        ) : (
          <LottieView
            autoPlay
            loop={false}
            onAnimationFinish={onDone}
            source={require("../assets/animations/done.json")}
            style={styles.animation}
          />
        )}
      </View>
    </Modal>
  );
}

const styles = StyleSheet.create({
  animation: {
    width: 150,
    flex: 1, //!!necessary!!
  },
  container: {
    alignItems: "center",
    flex: 1,
    justifyContent: "center",
  },
});

Reply for questions.