React Native navigation param doesn't get updated value - react-native

I have a React Native application where i'm taking input from one component and sending the input values as navigation params to other component where search is performed according to those input data. Now, it's working on first time when i'm getting the input values from receiving them with navigation.getParam.But when i go back to add some new inputs and go to the other component navigation.getParamshows the older value not the current one. Here's where i'm taking the inputs:
inputData = () => {
let bodyData = {
customer_id: this.state.customerId,
security_code: this.state.userSecurityCode,
vendor: this.state.vendor,
category_id: this.state.categoryName,
country_id: this.state.countryName,
zone_id: this.state.zoneName,
navigationIdentity: 1
}
this.props.navigation.navigate('Vendor',bodyData)
}
And here's i'm receiving:
componentWillMount() {
const { navigation } = this.props;
this.focusListener = navigation.addListener("didFocus", () => {
const customer_id = navigation.getParam('customer_id')
const security_code = navigation.getParam('security_code')
const vendor = navigation.getParam('vendor')
const category_id = navigation.getParam('category_id')
const country_id = navigation.getParam('country_id')
const zone_id = navigation.getParam('zone_id')
let searchBody = {
customer_id: customer_id,
security_code: security_code,
vendor: vendor,
category_id: category_id,
country_id: country_id,
zone_id: zone_id
}
console.log('in focus',searchBody)
});
}
Now the console.log here only shows the first input values received with navigation.getParam. After that when i update input values and navigate it still shows the first fetched values.

Hope this works
inputData = () => {
let bodyData = {
customer_id: this.state.customerId,
security_code: this.state.userSecurityCode,
vendor: this.state.vendor,
category_id: this.state.categoryName,
country_id: this.state.countryName,
zone_id: this.state.zoneName,
navigationIdentity: 1
}
this.props.navigation.push('Vendor',bodyData)
}
componentWillMount() {
const { params } = this.props.navigation.state;
this.focusListener = this.props.navigation.addListener("didFocus", () => {
const customer_id = params.customer_id;
const security_code = params.security_code;
const vendor = params.vendor;
const category_id = params.category_id;
const country_id = params.country_id;
const zone_id = params.zone_id;
let searchBody = {
customer_id: customer_id,
security_code: security_code,
vendor: vendor,
category_id: category_id,
country_id: country_id,
zone_id: zone_id
}
console.log('in focus',searchBody)
});
}

Related

How do I resolve a callback error with 'callback' is an instance of Object)?

TypeError: callback is not a function. (In 'callback(data)',
'callback' is an instance of Object)
The code here works just fine when I write it like this:
const onSelectFilterDone = (filter) => {
setFilter(filter);
setFilterModalVisible(false);
unsubscribe.current = listingsAPI.subscribeListings(
{ categoryId: category.id },
// { categoryId2: category2.id },
favorites,
onListingsUpdate,
);
};
When i uncomment that other line, it breaks and gives me this error.
const onSelectFilterDone = (filter) => {
setFilter(filter);
setFilterModalVisible(false);
unsubscribe.current = listingsAPI.subscribeListings(
{ categoryId: category.id },
{ categoryId2: category2.id },
favorites,
onListingsUpdate,
);
};
Here is the relevant snippet from listingsAPI (below) if it helps but this code works fine when there is only one object. Is there a specific way to make this work with two objects like above?
if (categoryId) {
return (
listingsRef
.where('categoryID', '==', categoryId)
.where('isApproved', '==', isApproved)
.onSnapshot((querySnapshot) => {
const data = [];
querySnapshot.forEach((doc) => {
const listing = doc.data();
if (favorites && favorites[doc.id] === true) {
listing.saved = true;
}
data.push({ ...listing, id: doc.id });
});
callback(data);
})
);
}
if (categoryId2) {
return (
listingsRef
.where('categoryID2', '==', categoryId2)
.where('isApproved', '==', isApproved)
.onSnapshot((querySnapshot) => {
const data = [];
querySnapshot.forEach((doc) => {
const listing = doc.data();
if (favorites && favorites[doc.id] === true) {
listing.saved = true;
}
data.push({ ...listing, id: doc.id });
});
callback(data);
})
);
}
You can combine your queries via this way if you want to have it optional:
let query = listingsRef.where('isApproved', '==', isApproved)
if (categoryId) {
query = query.where('categoryID', '==', categoryId)
}
if (categoryId2) {
query = query.where('categoryID2', '==', categoryId2)
}
query.onSnapshot...

React Native Redux issue

I am having an issue with adding favourite functionality for e-commerce app. Getting error of undefined.enter image description here
case TOGGLE_FAVOURITE:
const exitsIndex = state.favouriteProducts.findIndex((meal) => meal.id === action.productId);
if(exitsIndex >= 0) {
return { ...state, favouriteProducts: state.favouriteProducts.filter((meal) => meal.id !== action.productId) }
} else {
const favMeal = state.availableProducts.find((meal) => meal.id === action.productId);
return { ...state, favouriteProducts: state.favouriteProducts.concat(favMeal) };
}
This is my action:
export const toggleFavourite = id => {
return { type: TOGGLE_FAVOURITE, productId: id };
};
And this is my call function:
const toggleFavouriteHandler = useCallback(() => {
dispatch(toggleFavourite(productId));
}, [dispatch, productId]);
you have to check for the initial state, when you are doing findIndex on favouriteProducts , favouriteProducts is null.
so just check if
state.favouriteProducts === null and that should work
To prevent TypeError you should check if state.favouriteProducts is undefined or null.
In this case, i would use:
case TOGGLE_FAVOURITE:
if (!state.favouriteProducts) return false; // you need this
const exitsIndex = state.favouriteProducts.findIndex((meal) => meal.id === action.productId);
if (exitsIndex >= 0) {
return { ...state, favouriteProducts: state.favouriteProducts.filter((meal) => meal.id !== action.productId) }
} else {
const favMeal = state.availableProducts.find((meal) => meal.id === action.productId);
return { ...state, favouriteProducts: state.favouriteProducts.concat(favMeal) };
}
I found different solution. Now its working
case TOGGLE_FAVOURITE:
const addedFavourite = action.product;
const id = addedFavourite.id;
const product_name = addedFavourite.product_name;
const product_image = addedFavourite.product_image;
const product_description = addedFavourite.product_description;
const product_price = addedFavourite.product_price;
const category_id = addedFavourite.category_id;
let updatedFavouriteItem = new Product(
id,
product_name,
product_image,
product_description,
product_price,
category_id,
)
if(state.items[addedFavourite.id] != null){
let updatedCartItems = { ...state.items };
delete updatedCartItems[action.product.id];
return {
...state,
items: updatedCartItems,
}
}
return{
...state,
items: {...state.items, [addedFavourite.id]: updatedFavouriteItem }
}
}
return state;
}

Debounce mobx-react and props

I'm trying to debounce the method call: "chart.calculateChartData(props.answers)".
I tried:
- autorun
- reaction
- use-debounce from a react lib.
- setTimeout within calculateChartData
Each solution led to an update cycle or didn't work because MobX is not immutable.
Has someone a hint?
function QuantificationChart(props: QuantificationChartProps) {
const {t} = useTranslation();
const rootStore = useRootStore();
const chart = rootStore.formulaStore.getChart<Chart>(Chart.chartName);
const data = chart.calculateChartData(props.answers);
calculateChartData = (questionData: { [id: string]: number; } = {}) => {
let chartData = [];
for (let i = 0; i < this.numberOfYears + 1; ++i) {
let customData = {...questionData, "year" : i};
let chartEntry = {
cost: this.rootStore.formulaStore.calculateFormula(this.cost.formula, customData),
earn: this.rootStore.formulaStore.calculateFormula(this.earn.formula, customData),
sum: 0
};
chartEntry.sum = (chartEntry.earn - chartEntry.cost) + (chartData[i - 1]?.sum || 0);
chartData.push(chartEntry);
}
return chartData;
};
Hint: It's my first project with MobX
Found a solution. Seems to work:
Based on: https://mobx-react.js.org/recipes-effects
const [data, setData] = React.useState(chart.calculateChartData(props.answers));
React.useEffect(
() =>
autorun(() => {
setData(chart.calculateChartData(props.answers));
}, {delay: 1000}),
[],
);

Ramda, filter with or condition

let arr = [
{
name: 'Anna',
q: {
name: 'Jane'
}
}
];
const getName = R.prop('name');
const getQname = R.path(['q','name']);
A filter where any of these two functions passes.
Something like:
export const filterByName = (name) =>
R.filter(
R.or(
R.propEq(getName, name),
R.propEq(getQname, name)
)
)
Not working. How can I combine these two functions in a R.filter?
Use R.either with R.propEq for the name and R.pathEq from q.name:
const filterByName = (name) =>
R.filter(
R.either(
R.propEq('name', name),
R.pathEq(['q', 'name'], name)
)
)
const arr = [{"name":"Anna","q":{"name":"Jane"}},{"name":"Smite","q":{"name":"Jane"}},{"name":"Another","q":{"name":"One"}}];
console.log(filterByName('Anna')(arr))
console.log(filterByName('Jane')(arr))
console.log(filterByName('XXX')(arr))
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
If you want to use an external function to extract the values, you can use R.pipe. Extract all property values with R.juxt, and then use R.any with R.equal to check for equality.
const getName = R.prop('name');
const getQname = R.path(['q','name']);
const filterByName = (name) =>
R.filter(
R.pipe(
R.juxt([getName, getQname]), // get all names
R.any(R.equals(name)) // check if any of the equals to name
)
)
const arr = [{"name":"Anna","q":{"name":"Jane"}},{"name":"Smite","q":{"name":"Jane"}},{"name":"Another","q":{"name":"One"}}];
console.log(filterByName('Anna')(arr))
console.log(filterByName('Jane')(arr))
console.log(filterByName('XXX')(arr))
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
I would use either as it works with functions:
export const filterByName = (name) =>
R.filter(R.either(
R.propEq('name', name),
R.pathEq(['q', 'name'], name)));
or
const nameIs = R.propEq('name');
const qNameIs = R.pathEq(['q','name']);
export const filterByName = (name) =>
R.filter(R.either(nameIs(name), qNameIs(name)));
You could also write this in a point free style:
const nameIs = R.converge(R.or, [
R.pathEq(['name']),
R.pathEq(['q', 'name']),
]);
const onlyAnna = R.filter(nameIs('Anna'));
const onlyGiuseppe = R.filter(nameIs('Giuseppe'));
const data = [
{ name: 'Anna', q: { name: 'Jane' } },
{ name: 'Mark', q: { name: 'Mark' } },
{ name: 'Giuseppe', q: { name: 'Hitmands' } },
];
console.log('Anna', onlyAnna(data));
console.log('Giuseppe', onlyGiuseppe(data));
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>

How to unit test API calls with axios() in react-native with Jest

I am developing Sample Application in React-native . I used Jest to use unit testing, i don't have an idea about Jest Api call
I want to need without using Promises:
Here this is my Code:
this is My Function Code:
/**
* #description Action to call nilpick service ,on success increment route as well as mark the location as fulfilled
*/
function nilPick() {
return async (dispatch, getState) => {
const currentState = getState();
const { user, picking } = currentState;
const { currentRouteIndex, pickRoute } = getState().picking.pickRouteInfo;
const { workId } = picking.pickWorkInfo;
const nilPickItem = pickRoute[currentRouteIndex];
const currentItem = getCurrentItem(currentState);
const currentTime = dateFunctions.getCurrentUTC();
const nilpickedItem = [
{
orderId: nilPickItem.fulfillOrdNbr,
lineNbr: nilPickItem.ordLine,
pickUpcNbr: nilPickItem.upc,
pickDisplayTs: currentTime,
pickUom: currentItem.workDetail.uom,
pickedLoc: nilPickItem.location,
locationType: nilPickItem.locType,
locId: nilPickItem.locId,
pickByType: currentItem.workDetail.pickByType,
exceptionPick: false,
gtinPrefRankNbr: 0,
pickUpcTypeCd: 5100
}
];
const { status, statusText } = await pickingService.nilPick(nilpickedItem, user, workId);
if (status === 200 || statusText === 'Created') {
console.info('Item nilpicked');
if (currentRouteIndex < pickRoute.length) {
dispatch(incrementRoute());
} else {
Alert.alert(
'Nilpick Complete',
[
{
text: 'OK',
onPress: () => {
dispatch(endPicking());
}
}
],
{ cancelable: false }
);
console.log('End of pickwalk');
return;
}
} else {
console.info('error in nilpicking item ');
}
};
}
This is my code above method to Converting Like this below sample test Case:
This is sample Test i want to call Api How to implement in Jest
it('Test For nillPic', () => {
const initialState = {
picking: {
pickRouteInfo: {
"fulfillOrdNbr": pickRouteInfo.fulfillOrdNbr,
"orderLine": '1',
"upc": '4155405089',
"location": 'A-1-1',
"availableLocsToPick": '2',
'suggSubPendingPicks?': 'N',
'manualSubPendingPicks?': 'N',
"lineFullfilled": 'false',
"currentRouteIndex": 1,
"pickRoute": ['r1', 'r2', 'r3']
}
}
};
// console.log("state data...", initialState);
const store = mockStore(initialState);
store.dispatch(actions.pickRouteActions.nilPickSuccess());
const expectedAction = [{ type: 'INCREMENT_ROUTE' }];
const localActions = store.getActions();
expect(localActions).toEqual(expectedAction);
});
Finally This is my code Please . Thanks in Advance