I Have an app on react native. Debug mode works on ios. But Release mode not works. I tried change the optimization level but not helped. The problem that I don't see any error. Just not working some functional. And I can't debug release version of app. How to solve this problem?
As a last change we added following saga, when we remove calling this saga it works
import { select, take, takeLatest, call, put, fork, race } from 'redux-saga/effects';
import R from 'ramda';
import V from 'o-validator';
import * as actionCreators from './actions';
import { redirectTo, showModalError, showModal, showOtp, closeOtp, errorOtp, loader, keychainSet } from '../../../actions/app-actions';
import { storeSession, refreshSession } from '../../../actions/session-actions';
import I18n from 'react-native-i18n';
import {
KEYCHAIN_RESET,
KEYCHAIN_GET,
KEYCHAIN_RESULT
} from '../../../constants/action-types';
import { validatePassword, createCustomError, serverError } from '../../../services/utils';
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms))
export function * ChangePasswordWatcher( api, action ) {
yield fork( ChangePasswordFormWatcher, api, action );
}
export function * ChangePasswordFormWatcher(api, action){
while (true) {
yield race({
changePasswordProcess: call(ChangePasswordStart, api),
cancel: take(['CHANGE_PASSWORD_PASSWORD_RESET'])
});
//yield put( loader('hide') );
yield put( loader('hide') );
}
}
/**
* Change Password Sagas starter
*
* @param {function} api - api object
* @param {object} action - action from dispatch
* @returns
*/
export function * ChangePasswordStart(api, action) {
try {
while (true) {
const { formData } = yield take('CHANGE_PASSWORD_FORM_SUBMIT');
let oldPassword = formData.oldPassword;
let newPassword = formData.newPassword;
let newPasswordConfirmation = formData.newPasswordConfirmation;
yield put({
type: 'CHANGE_PASSWORD_FORM_VALID'
});
const validate = validateForm( 'changePasswordForm', formData );
if ( validate.valid ) {
yield put( actionCreators.submitChangePasswordFormValid() );
yield put( loader('show') );
let newPasswordResponse = yield call( api.setChangePassword, oldPassword, newPassword);
yield put( loader('hide') );
if ( !newPasswordResponse.ok ) {
let errors = serverError(newPasswordResponse);
console.log(errors);
console.log('errors newPasswordResponse');
yield put( showModalError({ error: errors }));
yield put( actionCreators.submitNewPasswordFormFailed( errors ) );
// return false;
}
else {
yield put({
type: KEYCHAIN_GET,
// resultAction: ''
});
const keychain = yield take(KEYCHAIN_RESULT);
// Save to Keychain
yield put( keychainSet({
login: keychain.login || false,
password: keychain.password || false
}) );
// final screen
yield put( redirectTo('thankyou') );
yield call( delay, 300 );
yield put( actionCreators.changePasswordResetState() );
}
}
else {
yield put( showModalError({ error: validate.errors }));
yield put( actionCreators.submitChangePasswordFormFailed( validate.errors ));
yield put( actionCreators.changePasswordFailed() );
// yield put( actionCreators.submitFinFormFailed( ret.errors ) );
// yield put( actionCreators.registrationFailed());
}
// Reset login
// yield call( delay, 300 );
// yield put( actionCreators.resetState() );
}
} catch (e) {
console.log(e);
}
}
export function validateForm( formKey, formData ) {
let
ret = {
valid: true,
errors: false
},
schema: {};
switch ( formKey ) {
case 'changePasswordForm':
schema = {
oldPassword: V.required( validatePassword ),
newPassword: V.required( validatePassword ),
newPasswordConfirmation: V.required( R.equals( formData.newPassword ) )
};
break;
default:
break;
}
ret.valid = V.validate( schema, formData );
if ( !ret.valid ) {
ret.errors = V.getErrors( schema, formData );
ret.errors = R.zipObj( R.pluck('property', ret.errors), ret.errors );
}
console.log('isValid: ' + ret.valid.toString());
return ret;
}
To comment all Console.log
statements not helped
import { select, take, takeLatest, call, put, fork, race } from 'redux-saga/effects';
import R from 'ramda';
import V from 'o-validator';
import * as actionCreators from './actions';
import { redirectTo, showModalError, showModal, showOtp, closeOtp, errorOtp, loader, keychainSet } from '../../../actions/app-actions';
import { storeSession, refreshSession } from '../../../actions/session-actions';
import I18n from 'react-native-i18n';
import {
KEYCHAIN_RESET,
KEYCHAIN_GET,
KEYCHAIN_RESULT
} from '../../../constants/action-types';
import { validatePassword, createCustomError, serverError } from '../../../services/utils';
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms))
export function * changePasswordScreenWatcher( api, action ) {
yield fork( ChangePasswordFormWatcher, api, action );
}
export function * ChangePasswordFormWatcher(api, action){
while (true) {
yield race({
changePasswordProcess: call(ChangePasswordStart, api),
cancel: take(['CHANGE_PASSWORD_PASSWORD_RESET'])
});
//yield put( loader('hide') );
yield put( loader('hide') );
}
}
/**
* Change Password Sagas starter
*
* @param {function} api - api object
* @param {object} action - action from dispatch
* @returns
*/
export function * ChangePasswordStart(api, action) {
try {
while (true) {
const { formData } = yield take('CHANGE_PASSWORD_FORM_SUBMIT');
let oldPassword = formData.oldPassword;
let newPassword = formData.newPassword;
let newPasswordConfirmation = formData.newPasswordConfirmation;
yield put({
type: 'CHANGE_PASSWORD_FORM_VALID'
});
const validate = validateForm( 'changePasswordForm', formData );
if ( validate.valid ) {
yield put( actionCreators.submitChangePasswordFormValid() );
yield put( loader('show') );
let newPasswordResponse = yield call( api.setChangePassword, oldPassword, newPassword);
yield put( loader('hide') );
if ( !newPasswordResponse.ok ) {
let errors = serverError(newPasswordResponse);
//console.log(errors);
//console.log('errors newPasswordResponse');
yield put( showModalError({ error: errors }));
yield put( actionCreators.submitNewPasswordFormFailed( errors ) );
// return false;
}
else {
yield put({
type: KEYCHAIN_GET,
// resultAction: ''
});
const keychain = yield take(KEYCHAIN_RESULT);
// Save to Keychain
yield put( keychainSet({
login: keychain.login || false,
password: keychain.password || false
}) );
// final screen
yield put( redirectTo('thankyou') );
yield call( delay, 300 );
yield put( actionCreators.changePasswordResetState() );
}
}
else {
yield put( showModalError({ error: validate.errors }));
yield put( actionCreators.submitChangePasswordFormFailed( validate.errors ));
yield put( actionCreators.changePasswordFailed() );
// yield put( actionCreators.submitFinFormFailed( ret.errors ) );
// yield put( actionCreators.registrationFailed());
}
// Reset login
// yield call( delay, 300 );
// yield put( actionCreators.resetState() );
}
} catch (e) {
//console.log(e);
}
}
export function validateForm( formKey, formData ) {
let ret = {
valid: true,
errors: false
};
switch ( formKey ) {
case 'changePasswordForm':
schema = {
oldPassword: V.required( validatePassword ),
newPassword: V.required( validatePassword ),
newPasswordConfirmation: V.required( R.equals( formData.newPassword ) )
};
break;
default:
break;
}
ret.valid = V.validate( schema, formData );
if ( !ret.valid ) {
ret.errors = V.getErrors( schema, formData );
ret.errors = R.zipObj( R.pluck('property', ret.errors), ret.errors );
}
//console.log('isValid: ' + ret.valid.toString());
return ret;
}
Based on the information provided, it seems like you're loading different bundles when switching between debug and release modes.
Make sure you configured your app to use a static bundle in Release Mode.
Then your app will render the same bundle in both modes, and the behavior may be as you're expecting.