Read from xlsx in javascript

URL of experiment: https://gitlab.pavlovia.org/pinartoptas/navontask

Description of the problem: I read my conditions.xlsx file at the beginning of the experiment using code component with the code below. At the beginning of each trial, I take the values of the first column row by row to determine the truth value of dummy loops that determine my trial type. I guess importing xlrd is not auto-translated to js and hence I got an error of -Unexpected token “*”-.

What is the best way to do the same thing in js, any suggestions?
Thanks in advance!

import xlrd

path = "conditions.xlsx"
inputWorkbook = xlrd.open_workbook(path)
inputSheet = inputWorkbook.sheet_by_index(0)

@pinar, you will not be able to import Python libraries in the JS code, so you will need a different solution. The easiest option would be to use the PsychoJS trialHandler to load your excel sheet. E.g.,

trials = new TrialHandler({
		psychoJS: psychoJS,
		nReps: 1, method: TrialHandler.Method.RANDOM,
		extraInfo: expInfo, originPath: undefined,
		trialList: 'conditions.xlsx',
		seed: undefined, name: 'trials'
	});

trialList = trials.getTrialList()

This will return a list of JS objects (equivalent a list of Python dicts) and you can iterate through the list to get the column values. E.g.,

trialList[0]['myColumnHeader']  // row 1
trialList[1]['myColumnHeader']  // row 2

@dvbridges Thank you for your quick response.

I added the code below into my code component in JS. It is repeated at the beginning of each trial. From what @dvbridges wrote above, I only changed ‘myColumnHeader’ to ‘trialType’ which is my column header in xlsx. However when I try to run it online I get the error: TypeError: Cannot read property ‘trialType’ of undefined
I tried defining trialType with var trialType, did not work.

Any suggestions how to solve this?
Thanks in advance.

r += 1;
    trials = new TrialHandler({
        psychoJS: psychoJS,
        nReps: 1, method: TrialHandler.Method.RANDOM,
        extraInfo: expInfo, originPath: undefined,
        trialList: 'conditions.xlsx',
        seed: undefined, name: 'trials'
        });
    
    trialList = trials.getTrialList()
    
    var trialType;
    
    condition = trialList[r]['trialType']

@pinar, is ‘trialType’ a header in your spreadsheet?

@dvbridges yes

Try using a different variable name, I used trials as an example, but trials is actually an important variable in PsychoJS. Try

r += 1;
navonTrials = new TrialHandler({
    psychoJS: psychoJS,
    nReps: 1, method: TrialHandler.Method.RANDOM,
    extraInfo: expInfo, originPath: undefined,
    trialList: 'conditions.xlsx',
    seed: undefined, name: 'navonTrials'
});
    
trialList = navonTrials.getTrialList()    
condition = trialList[r]['trialType']

@dvbridges Thanks, I did that. Now the error is: TypeError: Cannot read property ‘getTrialList’ of undefined - for line trialList = navonTrials.getTrialList()
New error = progress, right? :slight_smile:

The code provided by @dvbridges worked for me. I can’t replicate your most recent error message (post #7), and the name that I gave to the TrialHandler object didn’t matter.

But I did get error messages similar to your earlier one (post #3) when I declared variables using the ‘var’ command. The errors were thrown when the program tried to access the variables in a subsequent routine. Any variables declared using ‘var’ will be local to the routine you’ve declared them in and will not be visible to any subsequent routines in your program (hence they will be reported as undefined). If you want a variable to be global, just assign a value to it without using ‘var’. The compiler will then automatically declare it as a global variable. I’m not sure if this is any help.

Actually, I got exactly the same error message as the one you reported in post #3 when I mistyped the name of the ‘trialList’ argument in the TrialHandler constructor call (i.e. I put something other than the word ‘trialList’ here). But you seem to have typed this correctly. Perhaps it is worth checking that you don’t have any typos in the names of your arguments…

@rdkirkden thank you for your reply :slight_smile:
I did the following and it worked, hope it helps. trialType is the excel column header.


navonTrials = new TrialHandler({
    psychoJS: psychoJS,
    nReps: 1, method: TrialHandler.Method.SEQUENTIAL,
    extraInfo: expInfo, originPath: undefined,
    trialList: 'conditions.xlsx',
    seed: undefined, name: 'navonTrials'
});

newList = navonTrials.getTrialList();


if ((trialType === "navon")) {
    isNavon = true;
    isTiming = false;
    trial_number += 1;
} else {
    if ((trialType === "timing")) {
        isTiming = true;
        isNavon = false;
        trial_number += 1;
    }
}