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

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.

Related

Display an image when Blob is returned from an API

I’m writing a Vue app which uses the Microsoft Graph API and SDK for initial authentication on the front end and then uses different aspects of the API throughout the app. Like displaying emails, OneDrive files, etc.
I’m using the profile photo from a users Microsoft account to display an avatar to other users. My issue is that when I call {graphApi}/me/photo/$value the result returned is a Blob. This is the endpoint provided in MS Graph.
I’ve read the MS Graph docs thoroughly, combed MDN & other sources and have not found a way to transform this result into a simple image in my markup.
Template markup:
<template>
<img :src="userPhoto" :alt="user.displayName" />
</template>
Setup function logic:
<script setup>
import { client } from "./foobar"
const userPhoto = ref();
async function getPhoto(){
const photo = await client.api("/me/photo/$value").get()
console.log(photo.value)
userPhoto.value = photo
};
</script>
Returned result:
{Blob, image:{id: default, size:48x48}}
So how do I decode or download the Blob properly to display an image in my Vue markup?? I’ve tried createObjectURL and FileReader() without any luck. I’m sure there is a simple solution but I am not finding it. Thanks for the help.
Explanation:
In below snippet as you can see I am passing the objectId of the Employee fetched from Graph previously.
Then making call for employee to get their Avatar/DP
The Graph Profile Photo endpoint returns binary Data of the photo.
Convert that binary data into data:image/png;base64,<readAsDataURL> URL e.g. data:image/png;base64,iVBORw0KGgoAAAANSU...
Use in <img src="dataUrl"/>
let imageUrl = (await request.get(GRAPH_CONFIG.GRAPH_DP_ENDPT + objectId + "/photos/48x48/\$value", { responseType: 'arraybuffer', validateStatus: (status) => status === 200 || status === 404 }))
if (imageUrl.status === 200) {
let reader = new FileReader()
let blob = new Blob([imageUrl.data], {type: 'image/jpeg'})
reader.onload = (event) => {
return event.target?.result.toString();
}
reader.readAsDataURL(blob)
}

How to use remove() (Firebase SDK 9 web)

How to use "remove()" in SDK v9 web?
(context: I'm learning React Native (using Expo) and there's this todo app).
There are no examples in the documentation. Here is what I have:
// firebase
import app from "./firebaseConfig";
import {
getDatabase,
ref,
set,
push,
onValue,
remove,
child,
} from "firebase/database";
// etc
const db = getDatabase(app);
const taskListRef = ref(db, "tarefas/" + user);
const newTaskRef = push(taskListRef);
// etc
const handleDelete = (key) => {
remove(taskListRef).then(() => {
const findTasks = tasks.filter((item) => item.key !== key);
setTasks(findTasks);
});
};
So, this remove(taskListRef) is my problem. I don't know how to call it properly regarding the reference to the data location.
I've tried: remove(taskListRef.child(user)), remove(taskListRef.child(key)) etc... and a bunch of other similar things. The error always: wrong reference.
Here is the repo. Please, help. Thank you all in advance.
P.S.: hopefully I won't have to ask a similar question regarding update().

How to delete all products matching a collection - Shopify

I have this retarded amount of product in a collection on Shopify (over 50k products) and I would need to delete them all, is there a way I can automate that? All I can find on the internet is to use the "bulk edit tool" which is the most useless thing I've ever seen as it can only grab 50 products at a time.
I've tried automating a script to update the rows with the CSV export file, but it takes over 6 hours for 20K products to import. Plus, since there are hashtags in the title and handle, it apparently doesn't overwrite the products for some reason. So I just can't use the archive anymore...
Has anyone ran into this issue and found a solution?
Thank you!
When it comes to this kinds of tasks I usually write myself a quick dev console script that will do the job for me instead of relying on an app.
Here is a script that you can use in the dev console of your shopify admin page (just copy /paste):
let productsArray = [];
// Recursive function that will grab all products from a collection
const requestCollection = (collectionId, url = `https://${window.location.host}/admin/api/2020-10/collections/${collectionId}/products.json?limit=250`) => {
fetch(url).then(async res => {
const link = res.headers.get('link');
const data = await res.json();
productsArray = [...productsArray, ...data.products];
if(link && link.match(/<([^\s]+)>;\srel="next"/)){
const nextLink = link.match(/<([^\s]+)>;\srel="next"/)[1];
requestCollection(collectionId, nextLink)
} else {
initDelete(productsArray)
}
})
}
// Get CSRF token or the request will require password
const getCSRFToken = () => fetch('/admin/settings/files',{
headers: {
"x-requested-with": "XMLHttpRequest",
"x-shopify-web": 1,
"x-xhr-referer": `https://${window.location.host}/admin/settings/files`
}
}).then(res => res.text()).then(res => {
const parser = new DOMParser();
const doc = parser.parseFromString(res, 'text/html');
return doc.querySelector('meta[name="csrf-token"]').getAttribute('content')
})
// The function that will start the deleting process
const initDelete = async (products) => {
const csrfToken = await getCSRFToken();
products.forEach(item => {
fetch(`https://${window.location.host}/admin/api/2020-10/products/${item.id}.json`, {
method: "delete",
credentials: 'include',
headers: {
"x-csrf-token": csrfToken,
"x-requested-with": "XMLHttpRequest",
"x-shopify-web": 1,
"x-xhr-referer": `https://${window.location.host}/admin/settings/files`
}
})
})
}
And you start it by using requestCollection(ADD_YOUR_COLLECTION_ID_HERE).
To clarify the script, there are 3 main functions:
requestCollection - this handles the product grabbing from the collection. It's a recursive function since we can't grab more than 250 products at the same time.
getCSRFToken - this grabs the CSRF token since most of the post/update/delete request requires it or they will fail (I grab it from the files page)
initDelete - this function start the delete process where we stack all the request one of the other without waiting, you may want to await each request, but even if you crash your browser I think it will be still faster to repeat the process rather then wait for each request to finish.
If you plan to use this script please TEST IT BEFORE USING IT. Create a collection with a few products and run against that, in case there are issues. I've tested it on my side and it's working but it's a code I wrote in 10 minutes after midnight, there can be issues there.
Have in mind that this script will delete ALL products in the collection you specify in the requestCollection(1231254125) method.
PS: All of this can be done using a Private App as well with the products scope set to read/write, using a back-end language of your choice. The main difference will be that you won't need the CSRF token and most of the headers that I set above. But I like quick solutions that doesn't require you to pull out the big guns.

data not fetching from firestore in react native

i created a collection in firestore called user and added a document and gave it 7 fields, but when i try fetching the data back using onSnapshot it does not return back any data. this is the collection
this is my code:
firestore()
.collection('user')
.doc('LCqSZXM17WUWiWFahyj6')
.onSnapshot((row) => {
console.log(row.data());
});
in the console it logs an empty array
thanks in advance!!!
You need to include more information.
Anyway, do you check your access rule of the Firestore database?
const doc = db.collection('cities').doc('SF');
const observer = doc.onSnapshot(docSnapshot => {
console.log(`Received doc snapshot: ${docSnapshot}`);
// ...
}, err => {
console.log(`Encountered error: ${err}`);
});
The above code is official docs code. Check error callback first.

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.