Home > Software design >  React Native error: call: argument fn is undefined or null
React Native error: call: argument fn is undefined or null

Time:03-23

So I cloned a react-native project from github and tried to run it on my phone using an expo app. the app works but only in the log in page and i cannot log in, every time e log in it says "Alert" "Undefined".

this shows up in terminal every time i click login:

call: argument fn is undefined or null
at http://192.168.43.93:19000/node_modules\expo\AppEntry.bundle?platform=android&dev=true&hot=false&strict=false&minify=false:193709:21 in check
at node_modules\@redux-saga\core\dist\io-1d6eccda.js:355:2 in <global>
at node_modules\@redux-saga\core\dist\io-1d6eccda.js:423:24 in put
at http://192.168.43.93:19000/node_modules\expo\AppEntry.bundle?platform=android&dev=true&hot=false&strict=false&minify=false:195556:37 in loginUserAsync$
at node_modules\regenerator-runtime\runtime.js:63:36 in tryCatch
at node_modules\regenerator-runtime\runtime.js:294:29 in invoke
at node_modules\@redux-saga\core\dist\redux-saga-core.dev.cjs.js:1002:23 in end
at node_modules\@redux-saga\core\dist\redux-saga-core.dev.cjs.js:1087:6 in proc
at http://192.168.43.93:19000/node_modules\expo\AppEntry.bundle?platform=android&dev=true&hot=false&strict=false&minify=false:193307:15 in end
at node_modules\@redux-saga\core\dist\redux-saga-core.dev.cjs.js:717:5 in cb.cancel
at node_modules\@redux-saga\core\dist\redux-saga-core.dev.cjs.js:1014:5 in end
at node_modules\@redux-saga\core\dist\redux-saga-core.dev.cjs.js:1087:6 in proc
at node_modules\react-native\node_modules\promise\setimmediate\core.js:37:13 in tryCallOne
at node_modules\react-native\node_modules\promise\setimmediate\core.js:123:24 in setImmediate$argument_0 
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:123:14 in _callTimer
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:177:14 in _callImmediatesPass
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:437:30 in callImmediates
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:388:6 in __callImmediates
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:132:6 in __guard$argument_0
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:365:10 in __guard
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:131:4 in flushedQueue

this is from sagas/auth.js:

import { put, call, takeEvery } from 'redux-saga/effects';

import {
    USER_LOGIN,
    USER_LOGIN_REQUEST,
    USER_LOGIN_COMPLETED,
    USER_LOGIN_ERROR,

    USER_LOGOUT_REQUEST,
    USER_LOGOUT,
    USER_LOGOUT_COMPLETED,
    USER_LOGOUT_ERROR,
    SET_AUTH_USER
} from "../api/actions";

import { userLogin, userLogout } from '../api/auth';

export function* loginUserAsync(action) {

    try {
        yield put({type: USER_LOGIN_REQUEST});

        const response = yield call(userLogin, action.payload)
        
        if(response!==undefined && response.error) {
            yield call(alert(response.message))
        } else {
            yield put({type: SET_AUTH_USER, response});    
        }

        yield put({type: USER_LOGIN_COMPLETED});
    } catch(error) {
        yield put({type: USER_LOGIN_ERROR, error});
        console.log(error)
    }
}

export function* loginUser() {

    yield takeEvery(USER_LOGIN, loginUserAsync)

}

export function* logoutUserAsync(action) {

    try {
        yield put({type: USER_LOGOUT_REQUEST})

        yield put({type: USER_LOGOUT_COMPLETED});

    } catch(error) {
        
        yield put({type: USER_LOGOUT_ERROR, error});
    }
}

export function* logoutUser() {

    yield takeEvery(USER_LOGOUT, logoutUserAsync)

}

this is from api/auth.js:

import Constants from "expo-constants";

const BASE_URI = Constants.manifest.extra.base_uri
const API_KEY = Constants.manifest.extra.api_key

// Login
export function* userLogin(payload){
    const { username, password } = payload;
    console.log("hahahahahaha");
    console.log("Payload sent: ", payload);
    return yield fetch(`${BASE_URI}/api/api/v1/login?api_token=${API_KEY}&username=${username}&password=${password}`, {
        method: 'POST',
        body: JSON.stringify(payload)
    })
    .then((response) => response.json())
    .catch(error => ({ error }));
}

// Logout
export function* userLogout(payload) {
    return yield fetch(`${apiUrl}/logout`, {
                    method: 'POST',
                    headers,
                    body: JSON.stringify(payload)
                })
                .then((response) => response.json())
                .catch(error => ({ error }));
}

does anyone knows where the problem is?????

CodePudding user response:

If we take a look at the error message:

call: argument fn is undefined or null

It seems to be telling you that the argument of the call effect is undefined or null. fn in this case refers to the argument being a function. When using Call() you want to provide it with a function that it can invoke, in your case you are providing it with the function "alert" which is undefined:

yield call(alert(response.message))

I don't see alert being either defined in your file or imported from anywhere. So your error happens because you are trying to invoke an undefined function called 'alert'

CodePudding user response:

I believe that happens because you have used the method alert from Alert without importing it on sagas/auth.js. Your code on sagas/auth.js will be like this:

import { Alert } from 'react-native';

// Some code...

export function* loginUserAsync(action) {
  try {
    yield put({type: USER_LOGIN_REQUEST});

    const response = yield call(userLogin, action.payload)
      
    if(response!==undefined && response.error) {
      yield call(Alert.alert(response.message)) // Add Alert here
    } else {
      yield put({type: SET_AUTH_USER, response});
    }

    yield put({type: USER_LOGIN_COMPLETED});
  } catch(error) {
    yield put({type: USER_LOGIN_ERROR, error});
    console.log(error)
  }
}

// Some code...

  • Related