Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot read property 'toString' of null #1021

Closed
pjpronk opened this issue Dec 14, 2019 · 2 comments
Closed

Cannot read property 'toString' of null #1021

pjpronk opened this issue Dec 14, 2019 · 2 comments
Labels

Comments

@pjpronk
Copy link

pjpronk commented Dec 14, 2019

Description

I am using a mongoDB database and mongoose to save a session. I pass the serialised data into my saveSession function and upload it to my database.

When I load the session by using ig.state.deserialize() no error is thrown, but an error is throws when I try to use any other function of the igApiCleint.

In my database the cookies variable was saved as a string. I thought the problem lied here, so I thought I could solve the problem by saving it as a JSON object.
When I add the line
serialized.cookies = JSON.parse(serialized.cookies);
then the cookies are saved as a JSON object.

I thought this would fix the error, but unfortunately it did not. So now I don't really know where the error could lie.

Error

TypeError: Cannot read property 'toString' of null
    at Request.getDefaultHeaders (/VSCodeProjects/Swapper/node_modules/instagram-private-api/src/core/request.ts:188:103)
    at Request.send (/VSCodeProjects/Swapper/node_modules/instagram-private-api/src/core/request.ts:68:23)
    at UserRepository.search (/VSCodeProjects/Swapper/node_modules/instagram-private-api/src/repositories/user.repository.ts:32:48)
    at UserRepository.searchExact (/VSCodeProjects/Swapper/node_modules/instagram-private-api/src/repositories/user.repository.ts:45:31)
    at UserRepository.getIdByUsername (/VSCodeProjects/Swapper/node_modules/instagram-private-api/src/repositories/user.repository.ts:95:29)
    at Object.it (/VSCodeProjects/Swapper/tests/instafunctions.test.js:13:44)

Code

export{};
import {IgApiClient} from "instagram-private-api";
const Session = require('../models/models').Session;

/**
 * Loads the session to the database.
 *
 * @param par_username {string} - Username of the user to save session for.
 * @return {Promise<void>} - Empty promise.
 */
async function loadSession(par_username) : Promise<any>
{
   return Session.findOne({username: par_username}).then((result) => {
       return result;
   }).catch((error) => {
       return error;
   });
}

/**
 * Saves the session to the database.
 *
 * @param par_username {string} - Username of the user to save session for.
 * @param serialized {JSON} - Serialized session data.
 * @return {Promise<void>} - Empty promise.
 */
function saveSession(par_username : string, serialized : JSON) : void
{
    const query = {'username': par_username};
    const options = {
        upsert: true,
        useFindAndModify : false,
        new: true,
        setDefaultsOnInsert: true
    };
    const change = {$set:{'session' : serialized}};

    return Session.findOneAndUpdate(query, change, options, function(err, doc) {
        if (err) throw new Error(err);
    });
}


/**
 * Gets IgApiClient from username and password.
 * If a certain username has a session, then this session is used to create the IgApiClient
 *
 * @param username {string} - Username of the user to get IgApiClient for.
 * @param password {string} - Password of the user to get IgApiClient for.
 * @return {Promise<IgApiClient>} - Promise of an IgApiClient
 */
async function getIgApiClient(username : string, password : string) : Promise<IgApiClient> {

    //Create a new client to return back to the user.
    const ig = new IgApiClient();
    await ig.state.generateDevice(username);

    //The code that has to be executed after every request.
    //Saves the state and cookies to database.
    ig.request.end$.subscribe(async () => {
        const serialized = await ig.state.serialize();
//Line I thought would fix the problem
        //serialized.cookies = JSON.parse(serialized.cookies);
        delete serialized.constants;
        saveSession((await ig.account.currentUser()).username, serialized);
    });

    const existingSession = await loadSession(username);
    if(existingSession != null){
        //The code to load a user from the session database if it exists
        await ig.state.deserialize(existingSession.session).catch((error) => {
            throw new Error(error);
        });
        return ig;
    }
    else {
        //The code to create a user through login
        console.log("Creating session for: " + username);
        await ig.account.login(username, password).catch((error) => {
            throw new Error(error);
        });
        await ig.simulate.postLoginFlow();
        return ig;
    }

}
exports.getIgApiClient = getIgApiClient;
@pjpronk pjpronk added the bug label Dec 14, 2019
@Nerixyz
Copy link
Collaborator

Nerixyz commented Dec 14, 2019

The serialized output has euDCEnabled set to null, it should be undefined | boolean. Your state sets undefined to null. When saving the state (saveSession), you can use JSON.stringify(serialize) to "clear" any undefined values.

@pjpronk
Copy link
Author

pjpronk commented Dec 14, 2019

Thanks @Nerixyz for the fast reply!
Your solution worked perfectly by adding the line:
serialized = JSON.parse(JSON.stringify(serialized));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants