How to replace string for multiple lines in react js - reactjs

Screenshot1 Here i want to replace Special characters"E" with
"bold tag" but it is changing only in one line i want to replace for
all the lines which contains special character E & F please verify the
screenshot for the reference
import React from 'react'; import '../screens/MainScreen.css'; import
{ FaArrowRight } from 'react-icons/fa';
export default function MainScreen() {
// let formData = newFormData();
const onFileChange = async (e) => {
e.preventDefault()
const exampleFileReader = new FileReader()
exampleFileReader.onload = async (e) => {
var text = (e.target.result)
var result = text.replace("\u001bE","<b>").replace('\u001bF','</b>').replace('\u001b-1','<u>').replace('\u001b-0','</u>');
console.log(result,"result")
};
exampleFileReader.readAsText(e.target.files[0]) };
return (
<div>
<center>
<img src={Pic} style={{ width: '120px', height: '100px', marginTop: '40px' }} />
<h1 style={{
color: 'red', fontSize: 50,
textAlign: 'center', border: '1px solid green', width: '40%'
}}>Text to PDF Converter</h1>
</center>
<div className="container">
<input type="file" multiple={true} style={{ color: 'white', backgroundColor: "green", padding: 10, fontSize: 20, width: '20%',
paddingTop: 20, paddingBottom: 20 }}
onChange={(e)=>onFileChange(e)} />
<FaArrowRight size={50} color='red' />
<h1 style={{ color: 'white', backgroundColor: "red", padding: 10, fontSize: 20, width: '20%', paddingTop: 20, paddingBottom: 20 }}
>Convert</h1>
<FaArrowRight size={50} color='green' />
<h1 style={{ color: 'white', backgroundColor: "green", padding: 10, fontSize: 20, width: '20%', paddingTop: 20,
paddingBottom: 20 }}>PDF Download</h1>
</div>
</div> ) };

e.target.result is probably not correct, please console.log it and post the general e.target in order to help you better (try this)
const onFileChange = async (e) => {
e.preventDefault()
const exampleFileReader = new FileReader()
exampleFileReader.onload = async (e) => {
var text = (e.target.value)
var result = text.replace("\u001bE","<b>").replace('\u001bF','</b>').replace('\u001b-1','<u>').replace('\u001b-0','</u>');
console.log(result,"result")
};
exampleFileReader.readAsText(e.target.files[0]) };

Related

have Request failed with status code 400 error in react native

I am using Axios to get data from JSON files and I tried it in postman it works, also the app works but sometimes when I open the app this error appears: Request failed with status code 400 and data disappears can you help solve. am I fetching data in the wrong way?
if there another way to avoid this error please mention it
here is my code:
`
import { StyleSheet, Text, View, Image, ScrollView, TouchableOpacity, TextInput, Pressable, Dimensions } from 'react-native'
import React, { useEffect, useState } from 'react'
import { useNavigation, useRoute } from "#react-navigation/native";
import axios from 'axios';
import LottieView from 'lottie-react-native';
import { Rating } from 'react-native-stock-star-rating'
import { AntDesign } from '#expo/vector-icons';
const LoadingDirection = () => {
return (
<LottieView
ref={animation => {
animation = animation
}}
style={{
width: 210,
height: 210,
alignSelf: 'center'
}}
source={require('../../assets/gif/loading.json')}
autoPlay
loop
/>
)
}
const ArtistSearch = () => {
const route = useRoute()
let token = route.params.token
const navigation = useNavigation();
const [artist, setArtist] = useState([]);
const [loaded, setLoaded] = useState(false);
const [search, setSearch] = useState('');
const [masterData, setMasterData] = useState([]);
const [empty, SetEmpty] = useState(false)
const ArtistData = async () => {
const resp = await axios.get('https://api.spotify.com/v1/search?query=remaster%2520track%3ADoxy%2520artist%3AMiles%2520Davis&type=artist&market=ES&locale=en-US%2Cen%3Bq%3D0.9&offset=5&limit=10', {
method: "GET",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: "Bearer " + token,
},
})
return resp.data.artists.items;
};
useEffect(() => {
ArtistData().then(artists => {
setArtist(artists)
setMasterData(artists)
setLoaded(true);
}).catch(err => {
console.log(err)
});
}, []);
return (
<ScrollView>
<View style={{ alignItems: 'center', marginTop: 20 }}>
<Pressable>
<View style={styles.searchSection}>
<TextInput
style={styles.input}
placeholder="Search for an artist..."
underlineColorAndroid="transparent"
value={search}
/>
<AntDesign name="search1" size={24} color="Black" />
</View>
</Pressable>
</View>
{artist.map((data, i) => (
<TouchableOpacity onPress={() => { navigation.navigate('AlbumScreen',{artistId:data.id,token:token,artistName:data.name}) }} key={i}>
<View>
<View style={styles.paper}>
<Image source={{ uri: data.images.url }} style={{ height: 350, width: Dimensions.get('window').width - 40, resizeMode: 'cover' }} />
<View style={{ height: 1, width: Dimensions.get('window').width - 40, backgroundColor: 'gray', marginBottom: 10 }}></View>
<Text style={{ paddingLeft: 10, fontSize: 24, fontWeight: '600' }}>{data.name}</Text>
<Text style={{ color: 'gray', marginLeft: 10, marginBottom: 10 }}>{data.followers.total} followers</Text>
<View style={{ marginLeft: 10 }}>
<Rating stars={data.popularity / 2} maxStars={5} size={25} />
</View>
<View style={{ marginBottom: 20 }} />
</View>
</View>
</TouchableOpacity>
))}
{!loaded && LoadingDirection()}
</ScrollView>
)
}
export default ArtistSearch
const styles = StyleSheet.create({
paper: {
width: Dimensions.get('window').width - 40,
backgroundColor: 'white',
shadowColor: 'black',
shadowOffset: {
width: 0,
height: 4,
},
shadowOpacity: 0.002,
shadowRadius: 22,
elevation: 3,
margin: 8,
marginTop: 20,
marginLeft: 20,
marginRight: 20,
borderColor: 'gray',
borderWidth: 0.2
},
heading: {
fontSize: 17,
marginBottom: 5,
marginLeft: 10,
marginTop: 10
},
stars: {
display: 'flex',
flexDirection: 'row',
marginLeft: 10, marginBottom: 20
},
starUnselected: {
color: '#aaa',
},
starSelected: {
color: '#ffb300',
},
searchSection: {
width: Dimensions.get('window').width - 40,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
borderColor: 'Black',
borderWidth: 1,
borderRadius: 10,
paddingHorizontal: 10
},
searchIcon: {
padding: 10,
},
input: {
flex: 1,
paddingTop: 10,
paddingRight: 10,
paddingBottom: 10
},
})
`

I use \u00AD but the word breaks at another place, why?

The variable props.title is "Reichsbahn\u00ADausbesserungs\u00ADwerk Warschauer Straße" but the word breaks like this:
Reichsbahnausbesse-
rungswerk Warschauer Straße
How is this possible?
function Header(props) {
const navigation = useNavigation();
return (
<View style={[styles.header, props.noArrow ? styles.headerNoArrow : null ]}>
<Text style={[styles.headerText, props.style=="grey" ? styles.textDark : null ]}>{props.title}</Text>
{ !props.noArrow &&
<TouchableOpacity onPress={() => navigation.goBack()}>
<Image
style={{width: 24, height: 22, top: 8, marginRight: 25 }}
source={require('../../assets/images/arrow-left-yellow.png')}
/>
</TouchableOpacity>
}
</View>
)
}
export default Header
const styles = StyleSheet.create({
header: {
flexDirection: 'row',
marginBottom: 20,
paddingLeft: CSS.margin,
marginTop: 20,
minHeight: 70,
},
headerText: {
color: CSS.grey,
fontFamily: CSS.font1,
fontSize: CSS.headlineSize,
marginLeft: 5,
marginRight: 10,
lineHeight: CSS.headlineLH,
flex: 1,
},
headerNoArrow: {
marginBottom: 38
},
textDark: {
color: '#1A2637'
}
});
I guess you mistook the HTML entity with CSS code.
Html entities uses &xxxx; syntax.
.wrap {
width: 200px;
}
.shy {
content: '\u00AD';
}
<p class="wrap">Reichsbahn­ausbesserungs­werk Warschauer Straße</p>
<p class="wrap">Reichsbahn<span class="shy"></span>ausbesserungs<span class="shy"></span>werk Warschauer Straße</p>

Positioning a image over text

I'm trying to position an image over text in a view. Im trying to position it like this:
Im just having a bit of trouble centering the image in the view. Here is the code:
<View style={styles.trackerBox}>
<Text style={styles.trackerName}>Test</Text>
<Image
source={{
uri: "https://imageLink.png"
}}
style={styles.logo}
/>
{this.props.user.test_trackers
.map(x => x.type)
.includes("test") ? (
<Icon
name="check-circle"
color={"#00FF00"}
size={25}
style={styles.linked}
/>
) : null}
</View>
and the style:
trackerBox: {
width: width * 0.3,
borderRadius: 20,
backgroundColor: "#19405D",
height: width * 0.3,
justifyContent: "center"
},
trackerName: {
textAlign: 'center',
color: "white",
fontSize: 20,
},
logo: {
height: 25,
width: 25,
position: "absolute",
top: 10,
right: 0,
left: 0
},
Here's how to achieve what you want
import React from 'react';
import { Text, View, StyleSheet, Dimensions, Image } from 'react-native';
export default function App() {
return (
<View style={styles.trackerBox}>
<Image
source={{
uri:
'https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg',
}}
style={styles.logo}
/>
<Text style={styles.trackerName}>Test</Text>
</View>
);
}
const { width } = Dimensions.get('window');
const styles = StyleSheet.create({
trackerBox: {
width: width * 0.3,
borderRadius: 20,
backgroundColor: '#19405D',
height: width * 0.3,
justifyContent: 'center',
},
trackerName: {
textAlign: 'center',
color: 'white',
fontSize: 20,
},
logo: {
height: 25,
width: 25,
alignContent: 'center',
alignSelf: 'center',
},
});
You can also try it here https://snack.expo.io/-PrSEkZ24
I think you forget to add display: flex, take look at this.
const App = () => (
<div style={styles.trackerBox}>
<img style={styles.logo} src="https://cdn1.byjus.com/wp-content/uploads/2019/11/essay-on-christmas.png" />
<h5 style={styles.trackerName}>Title</h5>
</div>
);
const width = 400;
const styles = {
trackerBox: {
width: width * 0.3,
borderRadius: 20,
backgroundColor: '#19405D',
height: width * 0.3,
display:"flex",
flexDirection:"column",
justifyContent: 'center',
margin:"auto"
},
trackerName: {
textAlign: 'center',
color: 'white',
fontSize: 20,
margin: 5
},
logo: {
height: 25,
width: 25,
margin: "0 auto"
},
}
ReactDOM.render(<App />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>
You can use ImageBackground instead of Image from react-native
<ImageBackground style={styles.theImage} source={{uri : item.imageUrl}}>
<Text>Text as a child to ImageBackground</Text>
</ImageBackground>

update a value using useRef and useEffect

I need to get the left position of an element after elements got mounted to show a progress bar. It works on clicking links however when it got mounted the progressWidth is not getting calculated. basically, the useEffect seems running before the component is mounted!!!!
export default ({ task, selectedLocal, selectedScenarioId, taskId, selectedTaskId }: ITaskNavItem) => {
const isActiveNav = (match: any, location: object) => match;
const isBefore = taskId <= selectedTaskId;
const isActive = taskId === selectedTaskId;
const navItemWidth = 100;
const [progressWidth, setProgressWidth] = useState(0);
const ref = useRef<HTMLInputElement>(null);
useEffect(() => {
if (ref.current) {
console.log(ref.current.getBoundingClientRect().left);
setProgressWidth(ref.current.getBoundingClientRect().left);
}
});
const theme = getTheme();
const styles = StyleSheet.create({
navLink: {
display: 'flex',
fontSize: '12px',
textDecoration: 'none',
color: theme.palette.neutralPrimary
},
navLinkActive: {
color: theme.palette.neutralPrimary,
fontWeight: 'bold'
},
navTitle: {
width: `${navItemWidth}px`,
textAlign: 'center',
wordBreak: 'break-word',
wordSpacing: `${navItemWidth}px`
},
linkText: {
display: 'flex',
flexFlow: 'column',
'align-items': 'center'
},
navIndicator: {
borderRadius: '50%',
margin: '10px 0 0 0',
backgroundColor: theme.palette.white,
width: '30px',
height: '30px',
border: '2px solid',
borderColor: theme.palette.neutralPrimary,
position: 'relative',
'z-index': '3'
},
innerIndicator: {
position: 'absolute',
borderRadius: '50%',
width: '20px',
height: '20px',
backgroundColor: theme.palette.neutralPrimary,
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)'
},
activeNavIndicator: { borderColor: theme.palette.themePrimary },
activeInnerIndicator: { backgroundColor: theme.palette.themePrimary },
progress: {
marginTop: '59px',
'z-index': '2',
position: 'fixed',
left: '0',
width: `${progressWidth}px`,
borderBottom: '2px solid',
borderColor: theme.palette.themePrimary
}
});
return (
<div className={css(styles.navLink)}>
<NavLink
exact
isActive={isActiveNav}
className={css(isActive ? [styles.navLink, styles.navLinkActive] : styles.navLink)}
to={`/selectedLocal/${selectedLocal}/scenarios/${selectedScenarioId}/tasks/${taskId}`}
>
<div className={css(styles.linkText)}>
<div className={css(styles.navTitle)}> {task.title}</div>
<div
ref={ref}
className={css(
isBefore ? [styles.navIndicator, styles.activeNavIndicator] : styles.navIndicator
)}
>
<div
className={css(
isBefore ? [styles.innerIndicator, styles.activeInnerIndicator] : styles.innerIndicator
)}
/>
</div>
</div>
</NavLink>
{isActive && <div className={css(styles.progress)} />}
</div>
);
};
So when component is getting loaded I get image 1, when I click on the component I get image 2. What I need to happen is when component is getting loaded it should look like image 2.

Creating Tweet Display Box in ReactJS

I am using the following code to generate a Tweet input box which takes in text/video/image/emoji. And they can be in different combinations.
I am not sure how to generate a tweet display box which shows the final display containing text/image/emoji ? I understand I might need to put the different inputs in an array or some sort but what after that. My current code for display side is performing nothing and I am not sure where to go from here.
I am looking for display box to be of following form after a Submit Button:
Code components/EmojiPicker.js has:
import React, {useState} from 'react'
import ReactDOM from "react-dom";
import { Picker } from "emoji-mart";
import Button from "#material-ui/core/Button";
const EmojiPicker = ({ onSelect }) => {
const [show, setShow] = useState(false);
return (
<>
<Button
onClick={() => setShow(oldState => !oldState)}
style={{ width: "30px", height: "30px", borderRadius: "4px", border: "3px solid", display: "flex", alignItems: "center", justifyContent: "center",
background: "transparent"}}>
ej
</Button>
{ReactDOM.createPortal(
show && <Picker onSelect={onSelect} />,
document.body
)}
</>
);
};
export default EmojiPicker
Code components/FileInput.js has:
import React, {useRef} from 'react'
const FileInput = ({ onChange, children }) => {
const fileRef = useRef();
const onPickFile = event => {
onChange([...event.target.files]);
};
return (
<div
style={{
width: "35px",
height: "35px",
borderRadius: "3px"
}}
onClick={() => fileRef.current.click()}
>
{children}
<input
multiple
ref={fileRef}
onChange={onPickFile}
type="file"
style={{ visibility: "hidden" }}
/>
</div>
);
};
export default FileInput
Code components/tweetboxImgInp.js as:
import React, {useState, useEffect} from 'react'
const ImgIcon = () => (
<svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0h24v24H0z" fill="none" />
<path d="M14 13l4 5H6l4-4 1.79 1.78L14 13zm-6.01-2.99A2 2 0 0 0 8 6a2 2 0 0 0-.01 4.01zM22 5v14a3 3 0 0 1-3 2.99H5c-1.64 0-3-1.36-3-3V5c0-1.64 1.36-3 3-3h14c1.65 0 3 1.36 3 3zm-2.01 0a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h7v-.01h7a1 1 0 0 0 1-1V5z" />
</svg>
);
export const Img = ({ file, onRemove, index }) => {
const [fileUrl, setFileUrl] = useState(null);
useEffect(() => {
if (file) {
setFileUrl(URL.createObjectURL(file));
}
}, [file]);
return fileUrl ? (
<div style={{ position: "relative", maxWidth: "230px", maxHeight: "95px" }}>
<img
style={{
display: "block",
maxWidth: "230px",
maxHeight: "95px",
width: "auto",
height: "auto"
}}
alt="pic"
src={fileUrl}
/>
<div
onClick={() => onRemove(index)}
style={{
position: "absolute",
right: 0,
top: 0,
width: "20px",
height: "20px",
borderRadius: "50%",
background: "black",
color: "white",
display: "flex",
alignItems: "center",
justifyContent: "center"
}}
>
x
</div>
</div>
) : null;
};
export default ImgIcon
And App.js has:
import React, { useRef, useState } from "react";
import ImgIcon, {Img} from './components/tweetboxImgInp'
import EmojiPicker from './components/EmojiPicker'
import FileInput from './components/FileInput'
import "emoji-mart/css/emoji-mart.css";
import "./styles.css";
function App() {
const [text, setText] = useState("");
const [pics, setPics] = useState([]);
const textAreaRef = useRef();
const insertAtPos = value => {
const { current: taRef } = textAreaRef;
let startPos = taRef.selectionStart;
let endPos = taRef.selectionEnd;
taRef.value =
taRef.value.substring(0, startPos) +
value.native +
taRef.value.substring(endPos, taRef.value.length);
};
return (
<div style={{display: "flex", flexDirection: "column", border: "3px solid", borderRadius: "5px", width: "600px", minHeight: "200px", padding: "20px"}} >
<div style={{ display: "flex", flexDirection: "column", flex: 1, border: "1px solid", borderRadius: "5px", margin: "0px"}}>
<textarea
ref={textAreaRef}
value={text}
style={{ flex: 1, border: "none", minHeight: "150px" }}
onChange={e => setText(e.target.value)}
/>
<div style={{ display: "flex", flexDirection: "row", flexWrap: "wrap", background: "fbfbfb"}} >
{pics.map((picFile, index) => (
<Img key={index} index={index} file={picFile} onRemove={rmIndx =>
setPics(pics.filter((pic, index) => index !== rmIndx))}/>))}
</div>
</div>
<div style={{ display: "flex", flexDirection: "row", alignItems: "center", marginTop: "20px" }}>
<div style={{ marginRight: "20px" }}>
<FileInput onChange={pics => setPics(pics)}>
{/* <ImgIcon /> */}
Tes
</FileInput>
</div>
<EmojiPicker onSelect={insertAtPos} />
</div>
</div>
);
}
export default App
Edit: I am good with the display box accepting only 1 media file, text and few emoji. It will surprise me if I am the only one in 2019 looking to do it for fun.
Working Example
Click the codesandbox button to view the demo
The tweet display component is pretty straightforward. Its a flexbox column with two parts. First part of the column contains the tweet. The second part of the column contains the list of images/media elements. Emoji is part of the text component.
Tweet Display Component
const Tweet = ({ tweet: { text, images } }) => (
<div
style={{
margin: "20px",
border: "1px solid grey",
width: "600px",
padding: "20px",
borderRadius: "3px"
}}
>
<div>{text}</div>
{images.length > 0 && (
<div
style={{
display: "flex",
flexDirection: "row",
flexWrap: "wrap",
background: "fbfbfb",
padding: "30px 0"
}}
>
{images.map((img, i) => (
<Img key={i} file={img} index={i} isSingle={images.length === 1} />
))}
</div>
)}
</div>
);
For more info checkout this css-tricks article to get more info on css flex layout

Resources