Deconstruct url path with user input in react native - react-native

I'm looking to make a fetch request to an API, in my code I added a text input:
constructor(props) {
super(props)
this.state = {
UserInput: '',
}
}
<TextInput onChangeText={(UserInput) =>
this.setState({UserInput})} value={this.state.UserInput} />
I can definitely see UserInput variable if I render <Text>{this.state.UserInput}</Text> in my view, however I'm trying to use that variable to generate a dynamic url path for my api request.
The url looks like that https://api.trading.com/1.0/stock/msft/company msft is what I have to change by UserInput
In pure javascript, I usually do something like this:
const userstock = UserInput;
const path = "https://api.trading.com/1.0/stock/";
const end = "/company";
const url = path + userstock + end;
I changed var by const because it's react native but it's still not working,
Can't find variable: UserInput
I also tried https://api.trading.com/1.0/stock/${UserInput}/company can someone help on this please? Thanks

As you write,it works if you render <Text>{this.state.UserInput}</Text>!
Why not write like this:
const userstock = this.state.UserInput;
or :
"https://api.trading.com/1.0/stock/"+ this.state.UserInput +"/company"
I suggest you should read official document and learn more about props and state!

Related

React Native cheerio.load() not working properly neither is JSDOM library

Well I'm new to this app development thing especially react-native and I wanted to know when I'm trying to scrap a website using cheerio and axios in react-native and then save it to firebase realtime database in the following way:
and yes i have done all the imports and also initalized my app using firebaseConfig
const db = firebase.database();
async function loadFurniture() {
const Url = 'https://hoid.pk/product-category/bedroom/beds-bedroom/';
const html = await axios.get(Url); // fetch page
const $ = cheerio.load(html); //parse html String
const furniture = [];
$('.product-wrapper ').each((i, element) => {
const title = $(element).find('h2.product-name').text();
const imageUrl = $(element).find('img.primary_image').attr('src');
const price = $(element).find('span.woocommerce-Price-amount amount').text();
console.log(title);
furniture.push({ title, imageUrl, price });
});
// Save the furniture to the Firebase Realtime Database
db
.ref('/furniture/bed')
.set({
title: furniture.title,
price: furniture.price,
object_image : furniture.imageUrl,
})
.then(() => console.log('Data set.'));
console.log(furniture);
// Return the extracted information
return furniture;
}
and then calling this function in a button
<Button
title="Fetch"
onPress = {() => loadFurniture() }
/>
The data was not being scraped so I tried to console.log() the data being fetched.
Whenever I click the button there is no error but just a log [ Function initialize ] with respect to console.log(title)
And before anyone says yup I've looked into the structure and 9it does returns me my desired classes after axios.get()
I just want to know that if there's some error in my code or if I'm going wrong somewhere.
I tried to scrap furniture titles, images and prices from certain website and then save it to database for any further use but it's just not working.
I've checked my network issues the html page being scraped and everything else one can think of. Now i just want to know either my code is accurate or if there's some mistake.
I tired to scrap the data of same website using python and it scraps it perfectly.
Edit:
I found out that the cheerio.load() function is not working there was no problem with the database... Is there some problem with cheerio.load() in it's latest version "1.0.0-rc.12" ?? If so what's the solution... I've tried number of libraries and each is giving a different kind of error so cheerio might be the only possible solution so if there's an alternative way of using cheerio.load() in react native do let me know.

Can not replace query string via Vue router

I have a Vue app which needs to remove query parameter from url. Url looks like http://localhost:8080/campaigns/279707824dd21366?screenshot=1 Needs to remove screenshot param without redirect. So I found solution which looks like this:
if( this.$route.query.screenshot ) {
this.screenshot();
const query = this.$route.query;
delete query.screenshot;
this.$router.replace({query: null}).catch((error)=>{
console.log(error);
});
}
This throws me an error without redirect:
NavigationDuplicated: Avoided redundant navigation to current
location: "/campaigns/279707824dd21366?screenshot=1".
I also tried this:
if( this.$route.query.screenshot ) {
this.screenshot();
const query = this.$route.query;
query.screenshot = null;
this.$router.replace({query});
}
What is wrong with this code? Thanks for any help.

Invalid Call on require from props url

I am attempting to set imageContent into an <Image source={imageContent}/> by getting content using require(props.imageUrl). Strangely (to me at least), the code works if I set image explicitly but fails on using props.imageUrl when equating them returns true.
export const SomeComponent: React.FC<Props> = (props: Props) => {
if (props.imageUrl != null) {
const imageUrl = '../../assets/images/profile_avatar.png'; //hardcode
const imageUrlFromProps = props.imageUrl; //from Props
console.log(imageUrl === imageUrlFromProps); //true
//SectionImage = require(imageUrl); //Works
//SectionImage = require(imageUrlFromProps); //Err: Invalid Call
}
...
<Image source={SectionImage}/>
Ciao, for what I know, require doesn't work with dynamic value. According to this discussion, the reason of this problem is how require is loaded. Seems that require is loaded before runtime and if it doesn't find a resource at this time, it doesn't work .
If you really need to assign dynamic resource to require, what I always do is create an array of require like:
var resources = {
res1: require("res1.png"),
res2: require("res2.png"),
...
}
and then when I need to load one of these at runtime:
if (condition) {
SectionImage = resources.res1;
}
else SectionImage = resources.res2;
As Giovanni has suggested, require can't be dynamic. It expects static strings only (Imagine how would all static bundling would have worked if they were dynamic). The only reason I didn't vote that as the answer is because I wanted to make the component more generic. So instead of applying condition in component, I imported image from the parent component and passed into this component (which I directly set to Source).
From Parent:
import Avatar from '../../assets/images/profile_avatar.png'
...
<SomeComponent image={Avatar}/>
and in Somecomponent:
let sectionImage = props.image || null;
...
<Image source={sectionImage}/>

How can I use "<nuxt-link>" in content rendered with "v-html"?

I have a utilities plugin for Nuxt.js that I created with a method to parse hashtags and mentions and replace them with <nuxt-link>. I am then using v-html to inject the converted data back into the template. My issue is that the <nuxt-link> are not being parsed with v-html.
import Vue from 'vue';
Vue.mixin({
methods: {
replaceMentions(data) {
// Tags
const tagRegEx = /\[#tag:[a-zA-Z0-9_-]*\]/g;
let tagMatch;
while ((tagMatch = tagRegEx.exec(data)) !== null) {
const tag = Array.from(tagMatch[0].matchAll(/\[#tag:(.*?)\]/g));
data = data.replace(tag[0][0], '<nuxt-link to="/search?q=' + tag[0][1] + '">#' + tag[0][1] + '</a>');
};
// Users
const userRegEx = /\[#user:[a-zA-Z0-9_-]*\]/g;
let userMatch;
while ((userMatch = userRegEx.exec(data)) !== null) {
const user = Array.from(userMatch[0].matchAll(/\[#user:(.*?)\]/g));
data = data.replace(user[0][0], '<nuxt-link to="/users/' + user[0][1] + '">#' + user[0][1] + '</>');
};
return data;
}
}
});
Does anyone have any tips for how I could make these work as proper nuxt compatible links? I already tried using <a> and it works fine, I would just prefer to utilize proper nuxt compatible links.
I think the discussion here basically answers the question: https://github.com/nuxt-community/modules/issues/185
Summarized, there are two options:
Render the HTML with a full Vue build and then attach the rendered node.
(Preferred) Find the links in the HTML and make them call router push instead of their default action.

How to handle deep linking in react native / expo

I have posted about this previously but still struggling to get a working version.
I want to create a sharable link from my app to a screen within my app and be able to pass through an ID of sorts.
I have a link on my home screen opening a link to my expo app with 2 parameters passed through as a query string
const linkingUrl = 'exp://192.168.0.21:19000';
...
_handleNewGroup = async () => {
try {
const group_id = await this.createGroupId()
Linking.openURL(`${linkingUrl}?screen=camera&group_id=${group_id}`);
}catch(err){
console.log(`Unable to create group ${err}`)
}
};
Also in my home screen I have a handler that gets the current URL and extracts the query string from it and navigates to the camera screen with a group_id set
async handleLinkToCameraGroup(){
Linking.getInitialURL().then((url) => {
let queryString = url.replace(linkingUrl, '');
if (queryString) {
const data = qs.parse(queryString);
if(data.group_id) {
this.props.navigation.navigate('Camera', {group_id: data.group_id});
}
}
}).catch(err => console.error('An error occurred', err));
}
Several issues with this:
Once linked to the app with the query string set, the values don't get reset so they are always set and therefore handleLinkToCameraGroup keeps running and redirecting.
Because the URL is not an http formatted URL, it is hard to extract the query string. Parsing the query string returns this:
{
"?screen": "camera",
"group_id": "test",
}
It doesn't seem right having this logic in the home screen. Surely this should go in the app.js file. But this causes complications not being able to use Linking because the RootStackNavigator is a child of app.js so I do not believe I can navigate from this file?
Any help clarifying the best approach to deep linking would be greatly appreciated.