How do we run function if previous props change in react native - react-native

I get error: undefined is not a object evaluating prevProps.route.params.connectionString
At first prevProps.route.params.connectionString is undefined until it is set from a different function. Trying to figure out the best way to only run this.fetchApiData(connectionString) when the prop has changed.
componentDidUpdate(prevProps, prevState) {
const {connectionString} = this.props.route.params;
if (prevProps.route.params.connectionString !== connectionString) {
this.fetchApiData(connectionString);
}
}

Related

MLKit object detection in React Native - null is not an object

I am trying to implement object detection in my React Native project. I have followed all the necessary steps and documentation as outlined here https://github.com/artikq/react-native-mlkit-odt#readme and here https://www.npmjs.com/package/react-native-mlkit-odt
I am capturing am image and trying to use that uri to run the object detection
I ran this:
npm install react-native-mlkit-odt
This is my code:
import MlkitOdt, { ObjectDetectorMode } from 'react-native-mlkit-odt';
const [result,setResult] = useState({});
const [, setImage] = useState();
Inside my function
if (!data.uri) {
throw new Error('uri not fetched');
}
try {
setImage(data);
setResult(
await MlkitOdt.detectFromUri(data.uri, {
detectorMode: 1,
shouldEnableClassification: true,
shouldEnableMultipleObjects: true,
})
);
} catch (e) {
console.error(e);
}
I am getting the error: [TypeError: null is not an object (evaluating 'MlkitOdt.detectFromUri')]
Does anyone know where I am going wrong?

vue3: control property with a timed function

First of all, I am a new vuejs developer and my purpose is to get acquainted with Vue, so, not going to use any external plugins or components.
I am writing a simple alert component, which looks like this:
<Alert :show="showAlert" />
I want the show property to return back to false after 2 seconds. How can I do this from inside the component (i.e., not in the page where this component is used). I tried this:
import { computed } from 'vue';
export default {
props: ['show'],
setup(props) {
const shown = computed(() => {
if (props.show) {
setTimeout(() => {
console.log("hiding the alert...")
props.show = false
}, 2000);
}
return props.show.value
})
return { shown }
}
};
the compiler said:
14:15 error Unexpected timed function in computed function vue/no-async-in-computed-properties
16:19 error Unexpected mutation of "show" prop vue/no-mutating-props
My rational is that the delay of alert should be controlled by the alert component (which could be changed by a prop), but not forcing the caller to write some thing like:
function Alert(delay) {
showAlert = true
setTimeout(() => showAlert = false, delay)
}
There are 2 errors.
First vue/no-mutating-props, props are read only so you are not supposed to change it from within the component. It is still possible to change props from outside the component and pass down to it.
For this you should copy the value of props to your data()
data() {
return {
showAlert
}
}
You should be able to update showAlert with no problem.
The second error vue/no-async-in-computed-properties, you cannot write async function inside computed(), so the alternative is to use watch instead.

How to call useQuery as an async task

I am new to React Native and Apollo-Client. In my Screen there are three tabs and individual tabs is calling its own data. But due to useQuery UI is completely freezing and giving a very bad experience.
Is there any other way that I can call the useQuery in async manner or in any background task?
EDIT
function PlayerList(props) {
const [loading , setloading] = useState(true)
const [data, setData] = useState()
const [loadData, { tempLoading, tempError, tempData }] = useLazyQuery(query);
async function getData(){
loadData()
}
useEffect(() => {
if (tempData == undefined) {
getData()
}
})
if(tempLoading){
return
<View >....</View>
}
if(tempData) {
return ( <View> ... </View>) }
}
Please find the above code for better understanding.
Apollo Client uses fetch which is always asynchronous. The issue is that you are creating an infinite loop.
The object returned by the useLazyQuery hook you are destructuring does not have properties named tempLoading, tempError or tempData. See here for how to correctly rename variables when using destructuring syntax.
Because tempData is always undefined, your useEffect hook's callback will be called on every render.
Calling loadData on every render triggers another render.
By using useLazyQuery, you are unnecessarily complicating your code -- you should be using useQuery instead.
const { data, loading } = useQuery(query)
if (loading) {
return <View>....</View>
}
return <View>...</View>

using async data in my page using nuxtjs

I have read using async data or fetch is a better approach in pages in nuxtjs instead of using the created hook.
I am struggling to get my code to work though
I had the following (Which does work fine)
created () {
this.$store.dispatch('cases/getCase', this.$route.params.caseId );
},
But how would I change that to work with the async method instead please, and be able to return more than one state when I need to.
I tried the following
async asyncData ({ params }) {
const thisCase = await this.$store.dispatch('cases/getCase', this.$route.params.caseId );
// constant thisUser
return { thisCase }
// return { thisCase, thisUser}
},
but this generated an error
undefined is not an object (evaluating 'this.$store')
Can anyone tell me what I am doing wrong please
Thanks
this not available in asyncData/fetch. It is even stated in docs in special orange warning.
You do NOT have access of the component instance through this inside
asyncData because it is called before initiating the component.
And again as said in docs
method receives the context object as the first argument, you can use
it to fetch some data and return the component data.
Context is where from you should be getting your store. Here docs for context.
So your code would be
async asyncData ({ params, store }) {
const thisCase = await store.dispatch('cases/getCase', params.caseId )
return { thisCase }
},

how to map nested array in componentWillMount using react native

I am creating react-native app. I have an array and want to use value outside the looping. I have declared value in this.state={current_cat_id:'',} I have tried it in componentWillMount like:
componentWillMount() {
var ids = [];
this.props.data.map((dataImage,Index) => {
dataImage['main-head'].map((subchild,Index2) => {
ids.push(subchild['path'])
})
})
this.setState({current_cat_id: ids})
}
its returning blank page. is this right approch
it should work for you. try this:-
componentWillMount() {
var ids = [];
this.props.data.map((dataImage) => {
dataImage['main-head'] != undefined && dataImage['main-head'].map((subchild) => {
ids.push(subchild['path'])
})
})
this.setState({current_cat_id: ids})
}
componentWillMount is called before the render method is executed. It is important to note that setting the state in this phase will not trigger a re-rendering. Avoid introducing any side-effects or subscriptions in this method. Use componentDidMount() instead.