I am using terser to minify React-native code but I cannot seem to find the appropriate options needed to minify React-native code and so I am getting the error "Unexpected token operator (<)".
import {StyleSheet, Button, TextInput, View, Text, Alert} from 'react-native';
import React from 'react';
const FormInput = () => {
const [formValue, setFormValue] = React.useState({
username: '',
password: '',
email: '',
phone_number: '',
});
const handleChangeText = (key, value) => {
console.log('first');
setFormValue(prev => ({...prev, [key]: value}));
};
return (
<View style={styles.container}>
<Text style={styles.header}>Sign Up</Text>
<TextInput
style={styles.input}
onChangeText={value => handleChangeText('username', value)}
value={formValue.username}
placeholder="Username"
/>
<TextInput
style={styles.input}
onChangeText={value => handleChangeText('password', value)}
value={formValue.password}
placeholder="password"
secureTextEntry={true}
/>
<TextInput
style={styles.input}
onChangeText={value => handleChangeText('email', value)}
value={formValue.email}
placeholder="email"
type
/>
<TextInput
style={styles.input}
onChangeText={value => handleChangeText('phone_number', value)}
value={formValue.phone_number}
placeholder="phone_number"
/>
<Button
title="Sign Up"
onPress={() => Alert.alert('Cannot press this one')}
/>
</View>
);
};
export default FormInput;
const styles = StyleSheet.create({
container: {
flex: 1,
padding: '5%',
},
input: {
height: 40,
margin: 12,
backgroundColor: '#F1F1F1',
borderRadius: 10,
padding: 10,
},
signup_button: {
borderWidth: 1,
borderRadius: 10,
},
header: {
fontSize: 40,
fontWeight: '700',
textAlign: 'center',
color: '#000',
},
});
I am trying to minify or uglify this code, I have tried using terser as well.
terser index.js --parse spidermonkey --compress --comments --module -o index.min.js
I have tried multiple methods to minify and every method gives an error at the <TextInput> line.
ERROR: Unexpected token i in JSON at position 0
at JSON.parse (<anonymous>)
at D:\reactnative\forminput_test\src\form-test\node_modules\terser\dist\bundle.min.js:29917:40
at Array.reduce (<anonymous>)
at convert_ast (D:\reactnative\forminput_test\src\form-test\node_modules\terser\dist\bundle.min.js:29893:61)
at run_cli (D:\reactnative\forminput_test\src\form-test\node_modules\terser\dist\bundle.min.js:29916:29)
at run_cli (D:\reactnative\forminput_test\src\form-test\node_modules\terser\dist\bundle.min.js:29890:11)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Related
I am trying to make a ticket app that allows for people to create tickets based on work that needs done. Right now, I need help with the expandable view for each ticket card. What I'm wanting is when a user presses on a specific card, it will expand the view and provide more details for only that card. What it is currently doing is expanding the view for every ticket card in the list. I'm new to React Native and trying my best, but nothing has worked so far.
Here is my parent which is called Home:
import React, {useState, useEffect} from 'react';
import {styles, Colors} from '../components/styles';
import { SafeAreaView } from 'react-native';
import Ticket from '../components/Ticket';
const data = [
{
name: 'Josh Groban',
subject: 'U-Joint',
desc: 'The bolt that is meant to hold the u-joint in place has the head broken off from it. See attached picture.',
assignee: 'John Doe',
assigneeConfirmedComplete: 'NA',
dateReported: 'Tue Mar 8, 2022',
vehicle: 'Truck 1',
media: '',
key: '1',
isShowing: false
},
// code removed for brevity
];
const Home = ({navigation}) => {
const [ticketList, setTicketList] = useState(data);
const getTickets = () => {
setTicketList(data);
}
useEffect(() => {
getTickets();
}, []);
return (
<SafeAreaView style={styles.HomeContainer}>
<Ticket
ticketList={ticketList}
setTicketList={setTicketList}
/>
</SafeAreaView>
)
};
export default Home;
And here is the main component that has all of the ticket card configurations:
import React, {useState, useEffect} from 'react';
import {Text, FlatList, View, SafeAreaView, Button, Image, TouchableOpacity } from 'react-native';
import {styles, Colors} from './styles';
import {Ionicons} from '#expo/vector-icons';
const Ticket = ({ticketList, setTicketList}) => {
const defaultImage = 'https://airbnb-clone-prexel-images.s3.amazonaws.com/genericAvatar.png';
const [isComplete, setIsComplete] = useState(false);
const [show, setShow] = useState(false);
const showContent = (data) => {
const isShowing = {...data, isShowing}
if (isShowing)
setShow(!show);
}
const completeTask = () => {
setIsComplete(!isComplete);
}
return (
<SafeAreaView style={{flex: 1}}>
<FlatList showsVerticalScrollIndicator={false}
data={ticketList}
renderItem={(data) => {
return (
<>
<TouchableOpacity key={data.item.key} onPress={() => showContent(data.item.isShowing = true)}>
<View style={styles.TicketCard}>
<Image
style={styles.TicketCardImage}
source={{uri: defaultImage}}
/>
<View style={styles.TicketCardInner}>
<Text style={styles.TicketCardName}>{data.item.vehicle}</Text>
<Text style={styles.TicketCardSubject}>
{data.item.subject}
</Text>
</View>
<TouchableOpacity>
<Ionicons
name='ellipsis-horizontal-circle'
color={Colors.brand}
size={50}
style={styles.TicketCardImage}
/>
</TouchableOpacity>
<TouchableOpacity onPress={completeTask}>
<Ionicons
name={isComplete ? 'checkbox-outline' : 'square-outline'}
color={Colors.brand}
size={50}
style={styles.TicketCardButton}
/>
</TouchableOpacity>
</View>
<View style={styles.TicketCardExpand}>
<Text>
{show &&
(<View style={{padding: 10}}>
<Text style={styles.TicketCardDesc}>
{data.item.desc}
</Text>
<Text style={{padding: 5}}>
Reported by: {data.item.name}
</Text>
<Text style={{padding: 5}}>
Reported: {data.item.dateReported}
</Text>
{isComplete && (
<Text style={{padding: 5}}>
Confirmed Completion: {data.item.assigneeConfirmedComplete}
</Text>
)}
</View>
)}
</Text>
</View>
</TouchableOpacity>
</>
)}}
/>
</SafeAreaView>
)
};
export default Ticket;
Lastly, here are the styles that i'm using:
import {StyleSheet } from "react-native";
import { backgroundColor } from "react-native/Libraries/Components/View/ReactNativeStyleAttributes";
// colors
export const Colors = {
bg: '#eee',
primary: '#fff',
secondary: '#e5e7eb',
tertiary: '#1f2937',
darkLight: '#9ca3f9',
brand: '#1d48f9',
green: '#10b981',
red: '#ff2222',
black: '#000',
dark: '#222',
darkFont: '#bbb',
gray: '#888'
}
export const styles = StyleSheet.create({
HomeContainer: {
flex: 1,
paddingBottom: 0,
backgroundColor: Colors.bg,
},
TicketCard : {
padding: 10,
justifyContent: 'space-between',
borderColor: Colors.red,
backgroundColor: Colors.primary,
marginTop: 15,
flexDirection: 'row',
},
TicketCardExpand: {
justifyContent: 'space-between',
backgroundColor: Colors.primary,
},
TicketCardImage: {
width: 60,
height: 60,
borderRadius: 30
},
TicketCardName:{
fontSize: 17,
fontWeight: 'bold'
},
TicketCardSubject: {
fontSize: 16,
paddingBottom: 5
},
TicketCardDesc: {
fontSize: 14,
flexWrap: 'wrap',
},
TicketCardInner: {
flexDirection: "column",
width: 100
},
TicketCardButton: {
height: 50,
}
});
Any help is greatly appreciated!
Create a Ticket component with its own useState.
const Ticket = (data) => {
const [isOpen, setIsOpen] = useState(false);
const handlePress = () => {
setIsOpen(!isOpen);
}
return (
<TouchableOpacity
onPress={handlePress}
>
// data.item if you use a list, otherwise just data
<YourBasicInformation data={data.item} />
{isOpen && <YourDetailedInformation data={data.item} />}
</TouchableOpacity>
)
}
Render one Ticket for every dataset you have.
<List
style={styles.list}
data={yourDataArray}
renderItem={Ticket}
/>
If you don't want to use a List, map will do the job.
{yourDataArray.map((data) => <Ticket data={data} />)}
instead of setting show to true or false you can set it to something unique to each card like
setShow(card.key or card.id or smth)
and then you can conditionally render details based on that like
{show == card.key && <CardDetails>}
or you can make an array to keep track of open cards
setShow([...show,card.id])
{show.includes(card.id) && <CardDetails>}
//to remove
setShow(show.filter((id)=>id!=card.id))
I am creating an android application and I need to use the react-native-image-picker library but it is showing some error, the error is:
[Unhandled promise rejection: TypeError: null is not an object (evaluating '_reactNative.NativeModules.ImagePickerManager.launchImageLibrary')]
I have tried everything like changing to different versions as well, also I have used expo-image-picker which does not show an error while fetching an image from android but gives an error when uploading it to firebase.
Please help, I have been frustrated with this error.
import {
View,
Text,
Image,
StyleSheet,
KeyboardAvoidingView,
TouchableOpacity,
ActivityIndicator
} from "react-native";
import React, { useState } from "react";
import { TextInput, Button } from "react-native-paper";
import ImagePicker, { launchImageLibrary } from "react-native-image-picker";
import storage from "#react-native-firebase/storage";
import auth from '#react-native-firebase/auth';
import firestore, {getStorage, ref, uploadBytes} from '#react-native-firebase/firestore';
export default function SignUp({ navigation }) {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [image, setImage] = useState(null);
const [shownext, setShownext] = useState(false);
const [loading, setLoading] = useState(false);
if (loading) {
return <ActivityIndicator size='large' />
}
const userSignUp = async () => {
setLoading(true)
if (!email || !password || !image || !name) {
alert('fill all details correctly')
return false;
}
try {
const result = await auth().createUserWithEmailAndPassword(email, password);
firestore().collection('users').doc(result.user.uid).set({
name: name,
email: result.user.email,
uid: result.user.uid,
pic:image
})
setLoading(false)
}catch (err) {
alert('something went wrong from your side')
}
}
const pickImageAndUpload = () => {
console.log(1);
launchImageLibrary({ puality: 0.5 }, async (fileobj) => {
console.log(2);
console.log(fileobj);
const uploadTask = storage().ref().child(`/userprofilepic/${Date.now()}`).putFile(fileobj.uri);
uploadTask.on(
"state_changed",
(snapshot) => {
const progress =
(snapshot.bytesTransferred / snapshot.totalBytes) * 100;
if (progress == 100) alert("image uploaded");
},
(error) => {
alert("error uploading image");
},
() => {
getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
setImage(downloadURL);
});
}
);});
};
return (
<KeyboardAvoidingView behavior="position" style={{ alignItems: "center" }}>
<View style={styles.box1}>
<Text style={styles.text}>Welcome to chatapplication</Text>
<Image style={styles.img} source={require("../assets/wa-logo.png")} />
</View>
{!shownext && (
<>
<TextInput
style={{ width: 330, marginTop: 50, marginBottom: 30 }}
label="Email"
value={email}
mode="outlined"
onChangeText={(text) => setEmail(text)}
/>
<TextInput
style={{ width: 330, marginBottom: 30 }}
label="Password"
value={password}
mode="outlined"
onChangeText={(text) => setPassword(text)}
secureTextEntry
/>
</>
)}
{shownext ? (
<>
<TextInput
style={{ width: 330, marginTop: 50, marginBottom: 30 }}
label="Name"
value={name}
mode="outlined"
onChangeText={(text) => setName(text)}
/>
<Button
style={{ marginBottom: 30 }}
mode="contained"
onPress={() => { pickImageAndUpload() }}
>
Upload Profile Pic
</Button>
<Button
disabled={image?false:true}
mode="contained"
onPress={() => { userSignUp() }}>
SignUp
</Button>
</>
) : (
<Button
// disabled={email&&password?false:true}
mode="contained"
onPress={() => {
setShownext(true);
}}
>
Next
</Button>
)}
<TouchableOpacity onPress={() => navigation.goBack()}>
<Text style={{ margin: 10, textAlign: "center", fontSize: 18 }}>
Already have an account?
</Text>
</TouchableOpacity>
</KeyboardAvoidingView>
);
}
const styles = StyleSheet.create({
text: {
fontSize: 22,
color: "green",
margin: 20,
},
img: {
width: 200,
height: 200,
},
box1: {
alignItems: "center",
},
});
How do I handle multiple text inputs with only one onChange on React Native?
For example:
Name, age, nationality, eye color.
Additionally, how do I save all of the inputs with only one button? (I want to output a list with all of these inputs in the same "item")
Here's my code with what I did so far, I want to make a sort of movie diary where the user can register new movies they want to watch: (I'm a total beginner btw, so I'm not sure about how to do most things. I'm doing this project to learn)
import React, { useState } from 'react';
import { Button, StyleSheet, View, Text, TextInput, ScrollView } from 'react-native';
import AsyncStorage from '#react-native-async-storage/async-storage';
const Registration = props => {
const [enteredMovieName, setMovieName] = useState("");
const [enteredSynopsis, setSynopsis] = useState("");
const [enteredComments, setComments] = useState("");
const [enteredSource, setSource] = useState("");
const movieData = {
Name: enteredMovieName,
Synopsis: enteredSynopsis,
Comments: enteredComments,
Source: enteredSource,
};
const movieDataHandler = () => {
console.log(movieData);
};
return (
<ScrollView>
<View>
<View>
<Text style={styles.bodyHighlight}>Add new movie</Text>
</View>
<ScrollView>
<View>
<Text style={styles.addMovie} >Movie name:</Text>
<TextInput
placeholder='Cool Movie Name'
style={styles.inputContainer}
onChangeText={enteredText => setMovieName(enteredText)}
value={enteredMovieName}
/>
<Text style={styles.addMovie} >Sinopsis:</Text>
<TextInput
placeholder='Amazing Synopsis'
style={styles.inputContainer}
onChangeText={enteredText => setSynopsis(enteredText)}
value={enteredSynopsis}
/>
<Text style={styles.addMovie} >Comments (optional):</Text>
<TextInput
placeholder='Awesome Thoughts'
style={styles.inputContainer}
onChangeText={enteredText => setComments(enteredText)}
value={enteredComments}
/>
<Text style={styles.addMovie} >Where to watch (optional):</Text>
<TextInput
placeholder='Super Useful Link'
style={styles.inputContainer}
onChangeText={enteredText => setSource(enteredText)}
value={enteredSource}
/>
</View>
<View>
<Button
style={styles.addMovie}
title='ADD'
color='#a30b00'
onPress={movieDataHandler}
/>
<Button
style={styles.addMovie}
title='SEE COMPLETE LIST'
color='#cd5c5c'
onPress={() => {
props.navigation.navigate('Items Screen');
}}
/>
</View>
</ScrollView>
</View >
</ScrollView>
)
}
const styles = StyleSheet.create({
bodyHighlight: {
padding: 10,
margin: 5,
fontWeight: 'bold',
fontSize: 25,
textAlign: 'center',
backgroundColor: '#C4BDBA'
},
inputContainer: {
borderColor: 'black',
borderWidth: 2,
width: 380,
justifyContent: 'center',
alignItems: 'center',
marginHorizontal: 10,
marginBottom: 5,
},
addMovie: {
padding: 10,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'stretch',
marginHorizontal: 10,
},
})
export default Registration;
You can manage all states in an object. For example:
import React from 'react';
import {
SafeAreaView,
StyleSheet,
TextInput,
Button,
Alert,
} from 'react-native';
const UselessTextInput = () => {
const [user, setUserData] = React.useState({ name: '', age: 0 });
return (
<SafeAreaView>
<TextInput
style={styles.input}
onChangeText={(text) => setUserData({...user, name: text })}
value={user.name}
/>
<TextInput
style={styles.input}
onChangeText={(age) => setUserData({...user, age: age })}
value={user.age}
/>
<Button onPress={() => Alert.alert(`User name ${user.name}, age ${user.age}`)} title="click me" />
</SafeAreaView>
);
};
const styles = StyleSheet.create({
input: {
height: 40,
marginTop: 42,
borderWidth: 1,
padding: 10,
},
});
export default UselessTextInput;
create a new function and make changes to the a copied object and push the new object to the state
const handleChange=(key,value)=>{
const myState = user
myState[key] = value
setUserData(myState)
}
then pass the function call to onChangeText prop
<TextInput
style={styles.input}
onChangeText={(text) => handleChange('name', text)}
value={user.name}
/>
I stumbled upon this issue that whenever I type anything on the TextInput, there is no text being type, meaning its blank.
I am using typescript btw. Here's my FormInput code:
import React from 'react';
import {View, TextInput, StyleSheet} from 'react-native';
import {COLORS, FONTS} from '../../constants';
interface Props {
placeholderText: string;
labelValue: any;
}
const FormInput: React.FC<Props> = ({
placeholderText,
labelValue,
...restProps
}) => {
return (
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder={placeholderText}
autoCorrect={false}
value={labelValue}
{...restProps}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
marginVertical: 35,
},
input: {
paddingVertical: 25,
paddingHorizontal: 20,
borderRadius: 50,
borderWidth: 2,
borderColor: COLORS.transparent,
backgroundColor: COLORS.lightGray,
...FONTS.body3,
color: COLORS.darkgray,
},
});
export default FormInput;
And I added it on my LoginScreen like this:
interface Props {
placeholder: string;
keyBoardType: string;
secureTextEntry: string;
buttonTitle: string;
}
interface State {
email: string;
password: string;
}
export default class LoginScreen extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
email: '',
password: '',
};
}
render() {
return (
<View style={styles.container}>
<SafeAreaView>
<View style={styles.logoContainer}>
<Image style={styles.logo} source={images.logo} />
</View>
<Text style={styles.loginText}>Login</Text>
<View style={styles.textInputContainer}>
<FormInput
placeholderText="Your email..."
keyBoardType="email-address"
autoCapitalize="none"
autoCorrect="none"
labelValue={this.state.email}
onChangeText={(userEmail: any) =>
this.setState({email: userEmail})
}
/>
<FormInput
placeholderText="Your password..."
secureTextEntry={true}
labelValue={this.state.password}
onChangeText={(userPassword: any) =>
this.setState({password: userPassword})
}
/>
<FormButton
buttonTitle="Login"
onPress={() => Alert.alert('hello')}
/>
</View>
</SafeAreaView>
</View>
);
}
}
When I started typing. It looks like this:
Any idea what's causing this?
From React Native documentation: Note that some props are only available with multiline={true/false}. Additionally, border styles that apply to only one side of the element (e.g., borderBottomColor, borderLeftWidth, etc.) will not be applied if multiline=true. To achieve the same effect, you can wrap your TextInput in a View:
So just add multiline prop to your FormInput
const FormInput = ({ placeholderText, labelValue, ...restProps }) => {
return (
<View style={styles.container}>
<TextInput
style={styles.input}
placeholder={placeholderText}
autoCorrect={false}
multiline // -- this one!
value={labelValue}
{...restProps}
/>
</View>)}
I keep getting the following error: this.setState is undefined with my React Native project. I have never seen this error before in React, but React Native is new to me. I have done some research and there are many people suggesting to either use a constructor and bind(this) or use an arrow function in the onPress property. I have tried both, but neither seem to work. Please also note that my first 2 functions work fine it is the createUser function that is throwing the error. I would appreicate any help, thanks in advance. Here is my original code:
import React, {Component} from 'react';
import {ScrollView, StyleSheet, TextInput, Text, View, Image, Button } from 'react-native';
import firebase from '../firebase.js';
class Auth extends Component {
state = {
username: "",
password: "",
error: ""}
onChangeUsername= (event) => {
this.setState({ username: event.nativeEvent.text})
}
onChangePassword= (event) => {
this.setState({ password: event.nativeEvent.text})
}
createUser = (event) =>{
firebase.auth().createUserWithEmailAndPassword(this.state.username, this.state.password).catch(function(error) {
var errorCode = error.code;
var errorMessage = error.message;
if(errorCode === "auth/invalid-email")
{this.setState({error: 2})}
console.log(error.code);
console.log(error.message);
});
}
render(){
return(
<View style={{width: "100%", height: "100%", backgroundColor: "#eeeeee",flexDirection:"column", alignItems:"center", justifyContent:"center"}}>
<Text>Email</Text>
<TextInput
value={this.state.username}
autoCorrect={false}
onChange={this.onChangeUsername}
style={{width: "80%", height: "10%", backgroundColor: "white", padding: "2%", margin:"2%"}}
placeholder={"Enter Email"}
autoComplete={"off"}
/>
<Text>Password</Text>
<TextInput
value= {this.state.password}
autoCorrect={false}
onChange={this.onChangePassword}
style={{width: "80%", height: "10%", backgroundColor: "white", padding: "2%", margin:"2%"}}
placeholder={"Enter Password"}
secureTextEntry={true}
/>
<Button title="Sign Up" style={{backgroundColor: "blue", padding: "2%", margin:"2%"}} onPress={(e)=>{this.createUser(e)}}></Button>
<Text>{this.state.error}</Text>
<View style={{width: "100%", height:"20%"}}></View>
</View>
);
}
}
export default Auth;
I have tried replacing
state = {
username: "",
password: "",
error: ""}
with
constructor(props) {
super(props);
this.state = {
username: "",
password: "",
error: ""};
this.createUser = this.createUser.bind(this);
}
I have also tried replacing:
<Button title="Sign Up" style={{backgroundColor: "blue", padding: "2%", margin:"2%"}} onPress={this.createUser}></Button>
and
createUser = () =>{
with
<Button title="Sign Up" style={{backgroundColor: "blue", padding: "2%", margin:"2%"}} onPress={(e)=>{this.createUser(e)}}></Button>
and
createUser = (event) =>{
But neither of these have worked.
I think the problem is following setState:
{this.setState({error: 2})}
This is because the line
firebase.auth().createUserWithEmailAndPassword(this.state.username, this.state.password).catch(function(error) {
will change the this context due the use of function()
Change it to an arrow function to keep the this context.
-->
firebase.auth().createUserWithEmailAndPassword(this.state.username, this.state.password).catch((error) => {