tus-js-client icon indicating copy to clipboard operation
tus-js-client copied to clipboard

Tus client on React Native Expo

Open Riz-waan opened this issue 4 years ago • 3 comments

Question Hi, I tried running the React Native example on Expo and am getting an error.

Setup details

  • Runtime environment: Expo React Native
  • Used tus-js-client version: 2.2.0
  • Used tus server software: not sure used this endpoint https://tusd.tusdemo.net/files/

Code

/* eslint-disable no-console */

import React from "react";
import { StyleSheet, Text, View, Button, Image, Linking } from "react-native";
import * as Permissions from 'expo-permissions';
import * as ImagePicker from 'expo-image-picker';

import tus from "tus-js-client";

export default class FilePicker extends React.Component {
  constructor() {
    super();

    this.state = {
      uploadedBytes: 0,
      totalBytes: 0,
      file: null,
      status: "no file selected",
      uploadUrl: null,
    };

    this.startUpload = this.startUpload.bind(this);
    this.selectPhotoTapped = this.selectPhotoTapped.bind(this);
    this.openUploadUrl = this.openUploadUrl.bind(this);
  }

  selectPhotoTapped() {
    Permissions.askAsync(Permissions.MEDIA_LIBRARY).then((isAllowed) => {
      if (!isAllowed) return;

      ImagePicker.launchImageLibraryAsync({}).then((result) => {
        if (!result.cancelled) {
          this.setState({
            file: result,
            status: "file selected",
          });
        }
      });
    });
  }

  getFileExtension(uri) {
    const match = /\.([a-zA-Z]+)$/.exec(uri);
    if (match !== null) {
      return match[1];
    }

    return "";
  }

  getMimeType(extension) {
    if (extension === "jpg") return "image/jpeg";
    return `image/${extension}`;
  }

  startUpload() {
    const file = this.state.file;

    if (!file) return;

    const extension = this.getFileExtension(file.uri);
    const upload = new tus.Upload(file, {
      endpoint: "https://tusd.tusdemo.net/files/",
      retryDelays: [0, 1000, 3000, 5000],
      metadata: {
        filename: `photo.${extension}`,
        filetype: this.getMimeType(extension),
      },
      onError: (error) => {
        this.setState({
          status: `upload failed ${error}`,
        });
      },
      onProgress: (uploadedBytes, totalBytes) => {
        this.setState({
          totalBytes: totalBytes,
          uploadedBytes: uploadedBytes,
        });
      },
      onSuccess: () => {
        this.setState({
          status: "upload finished",
          uploadUrl: upload.url,
        });
        console.log("Upload URL:", upload.url);
      },
    });

    upload.start();

    this.setState({
      status: "upload started",
      uploadedBytes: 0,
      totalBytes: 0,
      uploadUrl: null,
    });
  }

  openUploadUrl() {
    Linking.openURL(this.state.uploadUrl);
  }

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.heading}>
          tus-js-client running in React Native
        </Text>

        {this.state.file !== null && (
          <Image
            style={{ width: 200, height: 200 }}
            source={{ uri: this.state.file.uri }}
          />
        )}

        <Button onPress={this.selectPhotoTapped} title="Select a Photo" />

        <Text>Status: {this.state.status}</Text>
        <Text>
          {this.state.uploadedBytes} of {this.state.totalBytes}
        </Text>
        <Button
          onPress={this.startUpload}
          title="Start Upload"
          accessibilityLabel="Start uploading a file"
        />

        {this.state.uploadUrl && (
          <Button
            onPress={this.openUploadUrl}
            title="Show Uploaded File"
            accessibilityLabel="Open uploaded file"
          />
        )}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
  heading: {
    fontSize: 20,
    fontWeight: "bold",
    marginBottom: 10,
  },
});

Error

TypeError: undefined is not an object (evaluating 'new _tusJsClient.default.Upload')
- node_modules/react-native/Libraries/LogBox/LogBox.js:148:8 in registerError
- node_modules/react-native/Libraries/LogBox/LogBox.js:59:8 in errorImpl
- node_modules/react-native/Libraries/LogBox/LogBox.js:33:4 in console.error
- node_modules/expo/build/environment/react-native-logs.fx.js:27:4 in error
- node_modules/react-native/Libraries/Core/ExceptionsManager.js:104:6 in reportException
- node_modules/react-native/Libraries/Core/ExceptionsManager.js:171:19 in handleException
- node_modules/react-native/Libraries/Core/setUpErrorHandling.js:24:6 in handleError
- node_modules/expo-error-recovery/build/ErrorRecovery.fx.js:9:32 in ErrorUtils.setGlobalHandler$argument_0
- node_modules/regenerator-runtime/runtime.js:63:36 in tryCatch
- node_modules/regenerator-runtime/runtime.js:293:29 in invoke
- node_modules/regenerator-runtime/runtime.js:63:36 in tryCatch
- node_modules/regenerator-runtime/runtime.js:154:27 in invoke
- node_modules/regenerator-runtime/runtime.js:164:18 in PromiseImpl.resolve.then$argument_0
- node_modules/react-native/node_modules/promise/setimmediate/core.js:37:13 in tryCallOne
- node_modules/react-native/node_modules/promise/setimmediate/core.js:123:24 in setImmediate$argument_0
- node_modules/react-native/Libraries/Core/Timers/JSTimers.js:130:14 in _callTimer
- node_modules/react-native/Libraries/Core/Timers/JSTimers.js:181:14 in _callImmediatesPass
- node_modules/react-native/Libraries/Core/Timers/JSTimers.js:441:30 in callImmediates
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:387:6 in __callImmediates
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:135:6 in __guard$argument_0
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:364:10 in __guard
- node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:134:4 in flushedQueue
* [native code]:null in flushedQueue
* [native code]:null in invokeCallbackAndReturnFlushedQueue

Riz-waan avatar Jan 10 '21 18:01 Riz-waan

Sadly, I do not have the time right now to look into this. However, we have an example React Native application, which should work https://github.com/tus/tus-js-client/tree/master/demos/reactnative Maybe it is worth for you to have a look at this.

Acconut avatar Jan 17 '21 23:01 Acconut

Same probleme here...

OroszD avatar Mar 05 '21 20:03 OroszD

Import this lib like the example does.

import * as tus from "tus-js-client";

jehartzog avatar Apr 08 '21 21:04 jehartzog

Import this lib like the example does.

import * as tus from "tus-js-client";

Saved me a lot of trouble mate. Thank you, the example does not import it the same way so this had me so confused

eeshankeni avatar Nov 18 '22 19:11 eeshankeni

Thank you! We updated the example in https://github.com/tus/tus-js-client/commit/a456406f8e4232db416705952da5ef49a661c7ef.

Acconut avatar Feb 14 '23 23:02 Acconut