I am making a real time betting app and My redux state is updating but my ui is not affecting Can anyone help me with the code - javascript

I am developing real time sportsbook using MERN stack and redis as memory db.. Everything seems right except react-redux not passing state to components as they are updated. I can see the nextstate clearly getting latest data in the console/ redux logger..
Here is the component reducer file..
import ActionTypes from './betslip.types';
import { calculateTotalReturn } from './betslip.utils';
const INITIAL_STATE = {
bets: [],
updateBet: true,
updatedGame: true,
betType:'single',
totalStake:0,
singleTotalReturn:0,
multiTotalReturn:0,
systemTotalReturn:0
}
export const betslipReducer = (state = INITIAL_STATE, action) => {
switch(action.type) {
case ActionTypes.SET_UPDATE_BET:
return {
...state,
updateBet: action.value
};
case ActionTypes.SET_BET_TYPE:
return {
...state,
betType: action.value
};
case ActionTypes.UPDATED_GAMES:
return {
...state,
updatedGame: !state.updatedGame
};
case ActionTypes.SET_TOTAL_STAKE:
return {
...state,
totalStake: action.value
};
case ActionTypes.PUT_BET:
return {
...state,
bets: [action.value, ...state.bets]
};
case ActionTypes.UPDATE_BET_ODD:
var betsOddsCopy = state.bets;
var indexOdds = betsOddsCopy.findIndex(n => n._id === action.betId);
betsOddsCopy[indexOdds].odds = action.value;
return {
...state,
bets: betsOddsCopy
};
case ActionTypes.UPDATE_BET_STAKE:
var betsStakeCopy = state.bets;
var indexStake = betsStakeCopy.findIndex(n => n._id === action.betId);
betsStakeCopy[indexStake].stake = action.value;
return {
...state,
bets: betsStakeCopy
};
case ActionTypes.DELETE_BET:
var betsCopy = state.bets;
const newBets = betsCopy.filter(b => b._id != action.betId)
return {
...state,
bets: newBets
};
case ActionTypes.CALCULATE_TOTAL_RETURN:
return calculateTotalReturn(state);
default:
return state;
}
}
The bets property in this file is not updating but betslip.bets is updating
import React, { useState } from 'react';
import { connect } from 'react-redux';
import { setUpdateBet, calculateTotalReturn, setBetType, setTotalStake, updateBetStake } from '../../redux/betslip/betslip.actions';
import Bet from '../bet/bet.component';
import './BetSlip.css';
//bets, updateBet, betType, totalStake, singleTotalReturn, multiTotalReturn, systemTotalReturn,
const BetSlip = ({bets, updateBet, betType, totalStake, singleTotalReturn, multiTotalReturn, systemTotalReturn, setUpdateBet, setBetType, setBetStake, setTotalStake, calculateTotalReturn }) => {
//const bets = store.getState().betslip.bets;
//console.log(betslip);
const [collapsed, setCollapsed] = useState(bets.length > 1 ? true : false);
const handleStakeTypeChange = (e) => {
if(e.target.dataset.type == 'multi' && bets.length > 8){
return;
} else if(e.target.dataset.type == 'system' && bets.length != 3){
return;
}
setBetType(e.target.dataset.type)
calculateTotalReturn();
}
const handleOpen = () => {
setCollapsed(!collapsed);
}
const handleUpdateBet = (e) => {
if(e.target.checked){
setUpdateBet(true);
} else{
setUpdateBet(false);
}
}
const handleStakeChange = (e) => {
if(betType == 'single'){
setBetStake(bets[0]._id, e.target.value)
calculateTotalReturn();
} else {
setTotalStake(e.target.value);
calculateTotalReturn();
}
//console.logbets);
}
React.useEffect(() => {
console.log('bet changed')
if(bets.length <= 1){
setBetType('single')
calculateTotalReturn();
}
calculateTotalReturn();
},[bets]);
// setInterval(() => {
// var total = 0;
// bets.forEach(bet => {
// total =+ bet.stake;
// })
// setTotalBetPrice(total);
// }, 5000);
var totalOdds;
if(betType == 'single'){
totalOdds = 0;
bets.forEach(bet => {
if( bet.odds != 'suspended'){
totalOdds += bet.odds;
}
//console.log('Hii');
})
} else if(betType == 'multi'){
totalOdds = 1;
bets.forEach(bet => {
if( bet.odds != 'suspended'){
totalOdds *= parseFloat(bet.odds);
}
})
} else {
totalOdds = 0;
}
//console.log(updatedGames)
return <div className='betslip__container'>
<div className='betslip__badge' onClick={handleOpen}>
<span>Bet Slip ({bets.length})</span>
{collapsed ? <span><i className="fa fa-chevron-up" /></span> : <span><i className="fa fa-chevron-down" /></span>}
</div>
{(collapsed == false && bets.length > 1) && <div className='betslip__stakeType'>
<div className={`betslip__stakeType__item ${betType == 'single' && "active"}`} onClick={handleStakeTypeChange} data-type='single'>
Single
</div>
{bets.length < 9 && <div className={`betslip__stakeType__item ${betType == 'multi' && "active"}`} onClick={handleStakeTypeChange} data-type='multi'>
Multi/Parlay
</div>}
{bets.length == 3 && <div className={`betslip__stakeType__item ${betType == 'system' && "active"}`} onClick={handleStakeTypeChange} data-type='system'>
System 2/3
</div>}
</div> }
<div className='betslip__body__container'>
{
collapsed == false && bets.map(bet => (
<Bet
key={bet._id}
id={bet._id}
title={bet.optionName}
odds={bet.odds} category={bet.category}
teams={bet.teams}
stake={bet.stake}
stakeType={betType} />
))
}
</div>
{!collapsed && <div className="betslip__footer">
{((betType == 'multi' || betType == 'system') || bets.length < 2) && <div className="betslip__stake">
<input type='number' className='betslip__stake__input' placeholder='Stake' value={betType == 'single' ? (bets[0].stake > 0 ? bets[0].stake : '') : (totalStake > 0 ? totalStake : '')} onChange={handleStakeChange} />
</div>}
<button className="betslip__btn__saving">
<span className="betslip__btn__saving__text">Place Bet</span>
<span className='totals'>
<span className='totals__text'>
Total Odds: {parseFloat(totalOdds).toFixed(3)}
</span>
{betType == 'single' && <span>Total Return: {singleTotalReturn > 0 ? parseFloat(singleTotalReturn).toFixed(2) : singleTotalReturn}</span>}
{betType == 'multi' && <span>Total Return: {multiTotalReturn > 0 ? parseFloat(multiTotalReturn).toFixed(2) : multiTotalReturn}</span>}
{betType == 'system' && <span>Total Return: {systemTotalReturn > 0 ? parseFloat(systemTotalReturn).toFixed(2) : systemTotalReturn}</span>}
</span>
</button>
</div>}
{!collapsed && <div className='betslip__badge'>
<div className="form-check">
{updateBet
?
<input className="form-check-input" type="checkbox" value="" id="flexCheckDefault" onClick={handleUpdateBet} defaultChecked />
:
<input className="form-check-input" type="checkbox" value="" id="flexCheckDefault" onClick={handleUpdateBet} />
}
<label className="form-check-label" htmlFor="flexCheckDefault">
Accept Change
</label>
</div>
</div>}
</div>
}
const mapStateToProps = state => ({
betType: state.betslip.betType,
updateBet: state.betslip.updateBet,
totalStake: state.betslip.totalStake,
singleTotalReturn: state.betslip.singleTotalReturn,
multiTotalReturn: state.betslip.multiTotalReturn,
systemTotalReturn: state.betslip.systemTotalReturn,
bets: state.betslip.bets
})
const mapDispatchToProps = dispatch => ({
setUpdateBet: value => dispatch(setUpdateBet(value)),
setBetType: value => dispatch(setBetType(value)),
setTotalStake: value => dispatch(setTotalStake(value)),
setBetStake: (id, value) => dispatch(updateBetStake(id, value)),
calculateTotalReturn: () => dispatch(calculateTotalReturn())
})
export default connect(mapStateToProps, mapDispatchToProps)(BetSlip);

Related

Wrong input validation

I want to validate all of my inputs in react
My validation code looks like this:
let isValid = {
name: false,
address: false,
postcode: false,
phone: false,
email: false
};
const validateInput = (e) => {
let currentInput = e.target
if (currentInput.name === 'name') {
if (currentInput.value !== 'undefined' && currentInput.value.match(/^[a-zA-Z]+$/)) {
isValid.name = true;
} else {
isValid.name = false;
}
}
if (currentInput.name === 'address') {
if (currentInput.value !== 'undefined') {
isValid.address = true;
} else {
isValid.address = false;
}
}
if (currentInput.name === 'postcode') {
if (currentInput.value !== undefined && currentInput.value.match(/^[0-9]+[-]+[0-9]+$/) && currentInput.value.length > 4) {
isValid.postcode = true;
} else {
isValid.postcode = false;
}
}
if (currentInput.name === 'phone') {
if (currentInput.value !== 'undefined' && currentInput.value.match(/^[0-9]+$/) && currentInput.value.length > 7) {
isValid.phone = true;
} else {
isValid.phone = false;
}
}
if (currentInput.name === 'email') {
if (currentInput.value !== 'undefined' && currentInput.value.match(/^(([^<>()[\]\\.,;:\s#"]+(\.[^<>()[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)) {
isValid.email = true;
} else {
isValid.email = false;
}
}
console.log(isValid)
}
For example when i type correct value in "Name" isValid.name gets value true, then when i write somethink in "address" isValid.address gets true, but isValid.name false
How to fix it?
{requiredInformations.map((el) => (
<>
<Label>{el.label}</Label>
<Input type={el.type} name={el.name} required onChange={(e) => { getInputValue(e); validateInput(e) }} />
</>
))}
I suggest you try to use react-joi library for validation React-Joi-Validation
Its easy and simple to use, and you can achieve what you are trying here in your code by just reading the first page on their npm package main page.
You need to get yourself familiar with terms like "state"
, "props", "component lifecycle", etc. Build a simple component using a guide on youtube, you can find plenty of them.
Meanwhile, here is a simple component that validates inputs:
function App() {
const [name, setName] = React.useState('');
const [address, setAddress] = React.useState('');
const isValid = React.useMemo(() => {
const result = {
name: false,
address: false,
};
if (name.match(/^[a-zA-Z]+$/)) {
result.name = true;
} else {
result.name = false;
}
if (address !== '') {
result.address = true;
} else {
result.address = false;
}
return result;
}, [name, address]);
return (
<div>
<input
placeholder="Name"
value={name}
onChange={(e) => setName(e.target.value)}
/>
{isValid.name ? <p>Name is valid</p> : <p>Name is invalid</p>}
<br />
<input
placeholder="Address"
value={address}
onChange={(e) => setAddress(e.target.value)}
/>
{isValid.address ? <p>Adress is valid</p> : <p>Adress is invalid</p>}
</div>
);
}
ReactDOM.render(<App />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root">
</div>

How to uncheck disabled radio button ? React.js

`
import React from 'react'
import {withRouter} from 'react-router-dom'
import './Size.style.scss'
class Size extends React.Component {
constructor(props) {
super(props);
this.checkboxRef = React.createRef();
}
componentDidUpdate(prevProps) {
if (
this.props.location.search !== prevProps.location.search &&
this.checkCategoryChanges(this.props.location.search, prevProps.location.search) &&
this.checkboxRef.current.checked
){
this.checkboxRef.current.checked = false;
}
}
checkCategoryChanges (currentUrl, prevUrl) {
let items = currentUrl.charAt(0) === '?' ? currentUrl.slice(1).split('&') : currentUrl.split('&');
for(const item of items) {
if(
(item.indexOf('categories') !== -1 && prevUrl.indexOf(item) === -1) ||
(item.indexOf('categories') !== -1 && items.length === 1 )
) {
return true;
}
}
return false;
}
isChecked(e) {
if(this.props.isChecked) {
if(e.checkboxRef.current && e.checkboxRef.current.checked === false) {
// e.checkboxRef.current.checked = true;
this.runOnChange(true);
return true;
}
}
const mainUrlAsArray = window.location.href.split('?');
if(mainUrlAsArray.length === 2) {
const url = mainUrlAsArray[1];
let checkedItems = url.charAt(0) === '?' ? url.slice(1).split('&') : url.split('&');
for(const item of checkedItems) {
if(item.indexOf(this.props.urlKey) !== -1 && item.split('=')[1].indexOf(this.props.value) !== -1) {
return true;
}
}
return false;
}
}
runOnChange(e) {
const checkboxData = {
value: this.props.value,
urlKey: this.props.urlKey,
isChecked: e,
type: this.props.type ? this.props.type : 'checkbox'
}
this.props.onChange(checkboxData);
}
render() {
return (
<>
<label className="size-label">
<input
ref = {this.checkboxRef}
defaultChecked={this.isChecked(this) ? true : undefined}
value={this.props.value}
onChange={(e) => this.runOnChange(e.target.checked)}
type={this.props.type ? this.props.type : 'checkbox'}
className="size-radio"
name="size"
disabled={this.props.disabled}
/>
<span className="size-button size-2">{this.props.label}</span>
</label>
</>
)
}
}
export default withRouter(Size)
`I have a radio buttons represent product sizes. I added default checked for the first radio button. And added quantity for product sizes. If product size quantity is 0 I add disabled={true}.But there is a problem, if my first size of product quantity is 0 it is still checked. I want to add default checked for the next radio button if first one is disabled ? But I can not solve this problem. Can anyone please help me ?
{this.state.colorData.map((size,index) =>
<Size
onChange={(e) => this.setState({size: e.value})}
key={index}
type="radio"
value={size.variation}
label={size.variation}
isChecked={index === 0 && this.state.size === ''}
disabled={size.qty ? false : true }
/>
)}

Onclick method in React is effecting every list item in a table, should only affect the one which is clicked

I have a tsx file which creates a table of comments. When the page is rendered, an array of information representing comments is gathered. A Set containing the indexes of the comments in the array, which is part of the state, determines whether a link under the comment reads 'show more' or 'show less'. Once that link is clicked, the index of the comment is added to the Set, and the state is updated with the addition of that index to the Set, if the Set contains the index of a comment when the state is updated, it should read 'show less'. The problem is when I click that link, it changes the link of each list element in the table, not just one.
import * as React from "react";
import { LocalizationInfo } from "emt-localization";
import { DateHandler } from "../handlers/date-handler";
import { UserIcon } from "./user-icon";
import { OnDownloadDocument } from "../models/generic-types";
import { getUserString } from "../models/user";
import { ClaimAction, ActionDetails, ReasonActionDetails, CommentDetails, DocumentDetails } from "../models/action";
const stateChangeActions = new Set<string>([
'Dispute',
'Rejection',
'SetUnderReview',
'Approval',
'Recall',
'Submission',
'RequestPartnerAction'
]);
const fiveMinutes = 5 * 60 * 1000;
const underscoreRegex = /_[^_]*_/g;
const actionTypeClassMap: {[actionType: string]: string} = {
'Submission': 'success',
'RequestPartnerAction': 'warn',
'Rejection': 'warn',
'Approval': 'success',
'Recall': 'warn',
'Dispute': 'warn',
'SetUnderReview': 'info',
'CustomerConsentDeclined': 'rejected'
};
const maxShortLength = 100;
interface ActionsProps {
readonly localization: LocalizationInfo;
readonly actions: ClaimAction[];
readonly onDownloadDocument: OnDownloadDocument;
readonly isInternalFacing: boolean;
readonly isHistoryPaneDisplay: boolean;
}
class ActionsState {
readonly expandedComments = new Set<number>();
}
export class Actions extends React.Component<ActionsProps, ActionsState> {
constructor(props: ActionsProps) {
super(props);
this.state = new ActionsState();
}
render():JSX.Element {
const loc = this.props.localization;
const isInternalFacing = this.props.isInternalFacing;
const toTime = (action:ClaimAction) => new Date(action.timeStamp).getTime();
const sortBy = (a:ClaimAction, b:ClaimAction) => toTime(b) - toTime(a);
const actions = this.props.actions.filter(action => {
if (isDocumentDetails(action.details)) {
if (action.actionType == 'DocumentSubmission' && action.details.documentType == 'Invoice') {
return false;
}
}
return true;
});
actions.sort(sortBy);
const grouped = groupActions(actions);
return (
<ul className={`claim-actions ${this.props.isHistoryPaneDisplay ? '' : 'user-comment-box'}`}>
{grouped.map((actions, index) => {
let actionClass = '';
actions.forEach(action => {
actionClass = actionClass || actionTypeClassMap[action.actionType];
});
const first = actions[0];
const icon = actionClass == 'success' ?
sequenceIcon('complete') :
actionClass == 'warn' ?
sequenceIcon('action-required') :
actionClass == 'rejected' ?
sequenceIcon('rejected') :
actionClass == 'info' ?
sequenceIcon('editing') :
<UserIcon
user={first.user}
isInternalFacing={isInternalFacing}
/>;
const elements = actions.map((action, actionIndex) => this.renderAction(action, actionIndex));
return (
<li className={actionClass} key={index}>
{icon}
<div className="win-color-fg-secondary">
<span className="claim-action-name win-color-fg-primary">
{ getUserString(first.user, isInternalFacing) }
</span>
<span className="text-caption">
{loc.piece("HistoryItemTitle", 0)}
{DateHandler.friendlyDate(first.timeStamp, true)}
</span>
</div>
{elements}
</li>
)
})}
</ul>
)
}
private renderAction(action:ClaimAction, actionIndex:number):JSX.Element|null {
const strings = this.props.localization.strings;
if (action.actionType == 'AddComments' || action.actionType == 'AddInternalComments') {
return this.renderComment((action.details as CommentDetails).comments, actionIndex);
}
const document = isDocumentDetails(action.details) ? action.details : null;
const documentLink = document ?
(key:number) =>
<a
key={key}
onClick={() => this.props.onDownloadDocument(document.documentId, document.name)}>
{document.name}
</a>
: null;
const locKey = `History_${action.actionType}`;
const localizedFlat = strings[locKey] || "";
const localized = replaceUnderscores(localizedFlat, documentLink);
const reason = (action.actionType === 'RequestPartnerAction' || action.actionType === 'Rejection') && action.details ? (action.details as ReasonActionDetails).reasonCode : '';
const reasonString = reason.charAt(0).toUpperCase() + reason.slice(1)
if (localized) {
return (
<div key={actionIndex}>
<div className="claim-action">
<span className="text-caption">{localized}</span>
</div>
<div className="claim-action">
{ reasonString && <span className="text-caption"><strong>{strings['ReasonLabel']}</strong>{` ${strings[reasonString]}`}</span> }
</div>
</div>
);
}
console.error(`Unknown action type ${action.actionType}`);
return null;
}
private renderComment(comment: string, actionIndex: number): JSX.Element {
const strings = this.props.localization.strings;
const canShorten = comment.length > maxShortLength;
const shouldShorten = canShorten && !this.state.expandedComments.has(actionIndex);
const shortened = shouldShorten ?
comment.substring(0, maxShortLength) + "\u2026" :
comment;
const paragraphs = shortened
.split('\n')
.map(s => s.trim())
.filter(s => s);
const elements = paragraphs.map((comment, i) =>
<div className="claim-comment" key={i}>
{comment}
</div>
);
const toggle = () => {
const next = new Set<number>(this.state.expandedComments);
if (next.has(actionIndex)) {
next.delete(actionIndex)
}
else {
next.add(actionIndex);
}
this.setState({ expandedComments: next });
}
const makeLink = (locKey:string) =>
<a
onClick={toggle}>{strings[locKey]}</a>;
const afterLink = canShorten ?
shouldShorten ?
makeLink('ShowMore') :
makeLink('ShowLess') :
null;
return (
<React.Fragment key={actionIndex}>
{elements}
{afterLink}
</React.Fragment>
);
}
}
// Function groups actions together under some conditions
function groupActions(actions:ClaimAction[]):ClaimAction[][] {
const grouped:ClaimAction[][] = [];
actions.forEach(action => {
if (grouped.length) {
const lastGroup = grouped[grouped.length - 1];
const timeDifference = new Date(lastGroup[0].timeStamp).getTime() - new Date(action.timeStamp).getTime();
if (stateChangeActions.has(lastGroup[0].actionType) && action.actionType == 'AddComments' && timeDifference < fiveMinutes) {
lastGroup.push(action);
return;
}
}
grouped.push([action]);
});
return grouped;
}
function isDocumentDetails(details:ActionDetails|null): details is DocumentDetails {
return !!details && (details.$concreteClass == 'InvoiceActionDetails' || details.$concreteClass == 'DocumentActionDetails');
}
function sequenceIcon(className: string):JSX.Element {
return (
<div className="sequence sequence-status claims-icon">
<div className={`step ${className}`} />
</div>
);
}
function replaceUnderscores(str: string, documentLink: ((k:number)=>JSX.Element)|null, startKey: number=0):JSX.Element[] {
if (!str) {
return [];
}
const match = underscoreRegex.exec(str);
if (!match) {
return replaceDocumentLink(str, documentLink, startKey);
}
const firstText = str.substring(0, match.index);
const middleText = match[0].substring(1, match[0].length - 1);
const lastText = str.substring(match.index + match[0].length);
const first = replaceUnderscores(firstText, documentLink, startKey);
const middle = [<strong className={'claims-emphasis'} key={startKey + first.length}>{middleText}</strong>];
const last = replaceUnderscores(lastText, documentLink, startKey + first.length + 1);
return first.concat(middle, last);
}
function replaceDocumentLink(str: string, documentLink: ((k:number)=>JSX.Element)|null, startKey: number=0):JSX.Element[] {
const replaceIndex = str.indexOf('{0}');
if (replaceIndex >= 0 && documentLink) {
return [
<React.Fragment key={startKey}>{str.substring(0, replaceIndex)}</React.Fragment>,
documentLink(startKey+1),
<React.Fragment key={startKey + 2}>{str.substring(replaceIndex+3)}</React.Fragment>
];
}
return [<React.Fragment key={startKey}>{str}</React.Fragment>];
}

iOS-redux updation not working Works fine in android

Problem :
Redux updation is not reflecting in UI in iOS
Code
return (
<React.Fragment>
{this.props.children}
{this.props.showNightOutFeedback &&
this.props.remainderNightoutFeedbackId &&
this.props.remainderNightoutFeedbackId.length > 0 &&
this.props.queueingPopups &&
this.props.queueingPopups.length > 0 &&
this.props.queueingPopups[0].popupName ===
queueActionTypes.ROUTE_FEEDBACK_POPUP && (
<FeedbackRatingScreen
routeName={
(this.props.nightOutDetails &&
this.props.nightOutDetails.route_name) ||
"Feedback for Route"
}
routeID={this.props.remainderNightoutFeedbackId[0]}
visible={this.props.showNightOutFeedback}
rating={
(this.props.nightOutDetails &&
this.props.nightOutDetails.total_rating) ||
0
}
onClose={() => {
this.props.showNightOutFeedbackModal(false);
this.props.deQueue();
}}
/>
)}
{this.props.showVenueFeedback &&
!isObjectEmpty(feedbackObj) &&
this.props.queueingPopups &&
this.props.queueingPopups.length > 0 &&
this.props.queueingPopups[0].popupName ===
queueActionTypes.VENUE_FEEDBACK_POPUP && (
<FeedbackAndRatingComponent
navigation={this.props.navigation}
data={feedbackObj ? feedbackObj : {}}
onClose={data => {
this.props.showVenueFeedbackFun(false);
this.props.updateFeedbackIsCompleted(data, true);
if (
this.props.remainderNightoutFeedbackId &&
this.props.remainderNightoutFeedbackId.length
) {
this.props.showNightOutFeedbackModal(true);
}
this.props.deQueue();
}}
/>
)}
{this.props.user &&
// this.props.showInviteScreenModal &&
this.props.queueingPopups &&
this.props.queueingPopups.length > 0 &&
this.props.queueingPopups[0].popupName ===
queueActionTypes.INVITE_SCREEN_POPUP && (
<InviteScreen
isInvite={this.props.queueingPopups[0].popupData.isInvite}
inviteId={this.props.queueingPopups[0].popupData.inviteId}
nightOutID={this.props.queueingPopups[0].popupData.nightoutId}
navigation={this.props.navigation}
navigateBack={this.props.navigateBack}
/>
)}
{this.props.user &&
// this.props.showInviteScreenModal &&
this.props.queueingPopups &&
this.props.queueingPopups.length > 0 &&
this.props.queueingPopups[0].popupName ===
queueActionTypes.INVITATION_ALERT_POPUP && (
<InviteScreen
isInvite={this.props.queueingPopups[0].popupData.isInvite}
inviteId={this.props.queueingPopups[0].popupData.inviteId}
nightOutID={this.props.queueingPopups[0].popupData.nightoutId}
navigation={this.props.navigation}
navigateBack={this.props.navigateBack}
/>
)}
{this.props.user &&
// this.props.showInviteScreenModal &&
!this.props.enterRoute &&
this.props.queueingPopups &&
this.props.queueingPopups.length > 0 &&
this.props.queueingPopups[0].popupName ===
queueActionTypes.INVITATION_START_POPUP && (
<InviteScreen
isInvite={this.props.queueingPopups[0].popupData.isInvite}
inviteId={this.props.queueingPopups[0].popupData.inviteId}
nightOutID={this.props.queueingPopups[0].popupData.nightoutId}
navigation={this.props.navigation}
navigateBack={this.props.navigateBack}
/>
)}
{!this.props.venues.enterVenues &&
//showModal.active &&
//this.props.venues.venueDetails.venue_enter[0] != undefined &&
(this.props.queueingPopups &&
this.props.queueingPopups.length > 0 &&
this.props.queueingPopups[0].popupName ===
queueActionTypes.ENTER_VENUE_POPUP &&
(shouldShowPopUpOrNot && (
<EnterRoutePopup
navigation={this.props.navigation}
visible={true}
isFreeRun={
this.props.venues.venueDetails.venue_enter.length &&
this.props.venues.venueDetails.venue_enter[0].isFreeRun
}
data={this.props.queueingPopups[0].popupData}
message={""}
onCloseModal={() => {
showModal.active = false;
this.props.closeModal();
}}
onClose={() => {
showModal.active = false;
this.props.closeModal();
this.props.deQueue();
// this.props.isPopupActiveFun(false);
}}
/>
)))}
{this.props.isVenueLoading &&
this.props.queueingPopups &&
this.props.queueingPopups.length > 0 &&
this.props.queueingPopups[0].popupName ===
queueActionTypes.LOADING_VENUE &&
VenueData.isVenueInARClicked && <LoaderPopup onClose={() => {}} />}
{this.props.showNavigateModalPopup &&
this.props.queueingPopups &&
this.props.queueingPopups.length > 0 &&
this.props.queueingPopups[0].popupName ===
queueActionTypes.NAVIGATE_VENUE_POPUP && (
<EnterRoutePopup
navigation={this.props.navigation}
visible={this.props.showNavigateModalPopup}
isFreeRun={true}
data={
this.props.venueNavigateData ? this.props.venueNavigateData : {}
}
onClose={() => {
this.props.showNavigateModalPopupFun(false);
// this.props.isPopupActiveFun(false);
this.props.deQueue();
}}
/>
)}
</React.Fragment>
);
}
mapStateToProps, mapDispatchToProps
is used to connect my queueReducer .
const popupQueuingReducer = (state = initialState, action) => {
switch (action.type) {
case queueActionTypes.ENQUEUE: {
let data = [];
data = state.queueingPopups;
let currentQueueData = null;
return {
...state,
queueingPopups: data
};
}
case queueActionTypes.PUSH: {
let data = state.queueingPopups;
// data.indexOf(action.data) == -1 &&
let currentQueueData = null;
currentQueueData = {
popupName: action.data.popupName,
popupData: action.data.queueData
};
data.unshift(currentQueueData);
return {
...state,
queueingPopups: data
};
}
case queueActionTypes.REMOVE_ENTER_VENUE: {
let data = state.queueingPopups;
data = data.filter(function(item) {
return item !== queueActionTypes.ENTER_VENUE_POPUP;
});
return {
...state,
queueingPopups: data
};
}
case queueActionTypes.REMOVE_LOGOUT: {
let data = state.queueingPopups;
data = data.filter(function(item) {
return item !== queueActionTypes.LOGOUT;
});
return {
...state,
queueingPopups: data
};
}
case queueActionTypes.REMOVE_VENUE_LOADING: {
let data = state.queueingPopups;
data = data.filter(function(item) {
return item.popupName !== queueActionTypes.LOADING_VENUE;
});
return {
...state,
queueingPopups: data
};
}
case queueActionTypes.REMOVE_PAUSE_POP_UP: {
let data = state.queueingPopups;
data = data.filter(function(item) {
return item.popupName != queueActionTypes.PAUSING_POP_UPS;
});
return {
...state,
queueingPopups: data
};
}
case queueActionTypes.DEQUEUE: {
let currentData = [];
currentData = state.queueingPopups;
if (currentData.length > 0) {
currentData.shift();
}
// state.queueingPopups.length && state.queueingPopups.shift();
return {
...state,
queueingPopups: currentData
};
}
case queueActionTypes.EMPTY_QUEUE: {
let data = state.queueingPopups;
data = data.filter(function(item) {
return (
item === queueActionTypes.PAUSING_POP_UPS ||
item === queueActionTypes.USER_MENU_POPUP
);
});
return {
...state,
queueingPopups: data
};
}
case queueActionTypes.RESTORE_STATE:
console.log("action.data" + action.data);
return {
...state,
queueingPopups: action.data
};
default:
return {
...state
};
}
};
export default popupQueuingReducer;
Working Scenario Explanation :
In adding certain alerts to queue(array) in my queueReducer and once am finished with one array I remove the item from queue. This change is supposed to pop the subsequent array type in my queue as any change in reducerState would be reflected in my js file since they are connected via mapStateToProps. This works fine in android but in iOS its not the expected bahaviour.
Is this got something to with Platform or code ??
Am totally confused as why its not working as it is simple state updations not something related to platform or so
Can anyone point me out what's wrong here ?
Any help would be appreciated.
Thanks in Advance
EDIT 1
Props are getting updated in store. As I can totally confirm that every single alert I want is in my queue and when each time my queue value changes componentWillReceive props is updated with new value. But am not able to see the reflection in UI
EDIT 2
Since #HMR pointed out as enqueue doesn't alter the array queue I tried changing two enqueue alert type to push but the results are same
EDIT 3
let dataToQueue = {
popupName: queueActionTypes.NAVIGATE_VENUE_POPUP,
queueData: data
};
dispatch(pushQueue(dataToQueue));
The above method is used to dispatch my event

Trying to set up form validation in my basic todo list app

I am trying to set up validations in my todo list app in react; however this doesn't seem to work. Even if the form is empty the process still goes through and I don't know where the problem is coming from. I am just following a tutorial online since I'm pretty new to this and don't know how to do it myself.
import React from "react";
import * as TodoActions from "../actions/TodoActions";
import TodoStore from "../stores/TodoStore";
import Todo from './Todo.js'
import './Todos.css'
const formValid = ({ formErrors, ...rest }) => {
let valid = true;
Object.values(formErrors).forEach(val => {
val.length > 0 && (valid = false);
});
Object.values(rest).forEach(val => {
val === null && (valid = false);
});
return valid;
};
export default class Todos extends React.Component {
constructor() {
super();
this.state = {
todos: TodoStore.getAll(),
loading: true,
formErrors: {
todo: ""
}
};
TodoActions.receiveTodos()
}
componentWillMount() {
TodoStore.addChangeListener(this.getTodos);
}
componentWillUnmount() {
TodoStore.removeChangeListener(this.getTodos);
}
componentDidUpdate() {
TodoActions.receiveTodos();
}
getTodos = () => {
this.setState({
todos: TodoStore.getAll(),
loading: false
});
}
deleteTodo = (id) => {
TodoActions.deleteTodo(id);
}
addItem = (e) => {
e.preventDefault();
TodoActions.createTodo(this._inputElement.value)
}
handleChange = e => {
e.preventDefault();
const { name, value } = e.target;
let formErrors = { ...this.state.formErrors };
switch (name) {
case "todo":
formErrors.todo =
value.length < 0 ? "Task cannot be empty" : "";
break;
default:
break;
}
this.setState({ formErrors, [name]: value }, () => console.log(this.state));
}
render() {
const { todos } = this.state;
const { formErrors } = this.state;
let TodoComponents;
if (this.state.loading) {
TodoComponents = <h1>Loading...</h1>;
} else if(todos.length) {
TodoComponents = todos.map((todo) => {
return (
<div key={todo.id} className="todo-list">
<Todo key={todo.id} name={todo.name}/>
<div className="todo-btn"><a type="button" onClick={() => this.deleteTodo(todo.id)} className="delete-btn"><i class="fas fa-trash-alt"></i></a></div>
</div>
)
});
} else {
TodoComponents = <p>No tasks to show :)</p>
}
return (
<div className="main-container">
<div className="small-container">
<h1 className="title">All Tasks</h1>
<ul>{TodoComponents}</ul>
<form onSubmit={this.addItem}>
<input ref={(a) => this._inputElement = a} placeholder="Enter Task" className="input-form {formErrors.todo.length < 0 ? 'error' : null}"/>
{formErrors.todo.length < 0 && (
<span className="errorMessage">{formErrors.firstName}</span>
)}
<button type="submit" className="input-btn">Add</button>
</form>
</div>
</div>
);
}
}

Categories