W
Wasp4w ago
Nuno

OpenSaaS serverside actions/queries problem

Hi, I am using wasp version 0.16.0 and the openSaaS tempalte on linux and I am experiencing some troubles using queries/actions on the server side. To reproduce: -create a new folder in src (let say /error. -make @src/error/queries.js file with this code;
const tasks = [
{ id: 1, description: 'Buy some eggs', isDone: true },
{ id: 2, description: 'Make an omelette', isDone: false },
{ id: 3, description: 'Eat breakfast', isDone: false },
]
export const getAllTasks = () => {
return tasks
}
const tasks = [
{ id: 1, description: 'Buy some eggs', isDone: true },
{ id: 2, description: 'Make an omelette', isDone: false },
{ id: 3, description: 'Eat breakfast', isDone: false },
]
export const getAllTasks = () => {
return tasks
}
-create another file; @src/error/queries2.js with this code:
import { getAllTasks } from "wasp/server/operations";

// The 'args' object is something sent by the caller (most often from the client)
export const getFilteredTasks = async (args) => {
const { isDone } = args;

// Fetch all tasks using getAllTasks
const allTasks = await getAllTasks();

// Filter the tasks
return allTasks.filter((task) => task.isDone === isDone);
};
import { getAllTasks } from "wasp/server/operations";

// The 'args' object is something sent by the caller (most often from the client)
export const getFilteredTasks = async (args) => {
const { isDone } = args;

// Fetch all tasks using getAllTasks
const allTasks = await getAllTasks();

// Filter the tasks
return allTasks.filter((task) => task.isDone === isDone);
};
Define the queries in the main.wasp file;
query getAllTasks {
fn: import { getAllTasks } from "@src/error/queries.js"
}

query getFilteredTasks {
fn: import { getFilteredTasks } from "@src/error/queries2.js"
}
query getAllTasks {
fn: import { getAllTasks } from "@src/error/queries.js"
}

query getFilteredTasks {
fn: import { getFilteredTasks } from "@src/error/queries2.js"
}
Now it throws an error: [ Server!] code: 'ERR_MODULE_NOT_FOUND', [ Server!] url: 'file:///home/nuno120/Documents/BELLEN-AIPERSONAL/test2/app/.wasp/out/sdk/wasp/dist/ext-src/payment/plans' [ Server!] } [ Server!] Node.js v20.17.0 [ Server ] [nodemon] app crashed - waiting for file changes before starting... When i change the import of the task in queries2.js to this: import { getAllTasks } from "wasp/ext-src/error/queries"; it works again btw! But not with the wasp/server/operations. Anyone knows why/how to fix? Also I don't understand why it throws an error in the payment/plants file and it get's fixed when I change the import in another file....
11 Replies
kapa.ai
kapa.ai4w ago
Hi @Nuno. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Thank you for your detailed question about using server-side actions and queries in Wasp 0.16.0 with the OpenSaaS template. I'll address the issues you're experiencing based on the information provided in the knowledge sources. The main problem you're encountering is related to importing operations on the server side. There are a couple of important points to note: 1. Incorrect import path: The error you're seeing is due to an incorrect import path. When working on the server side, you should import operations from wasp/server/operations instead of wasp/client/operations. 2. Context handling: When calling operations on the server side, you need to provide the context as the first argument. To fix your issue, you should modify your queries2.js file as follows:
import { getAllTasks } from "wasp/server/operations";

export const getFilteredTasks = async (args, context) => {
const { isDone } = args;

// Fetch all tasks using getAllTasks
const allTasks = await getAllTasks({}, context);

// Filter the tasks
return allTasks.filter((task) => task.isDone === isDone);
};
import { getAllTasks } from "wasp/server/operations";

export const getFilteredTasks = async (args, context) => {
const { isDone } = args;

// Fetch all tasks using getAllTasks
const allTasks = await getAllTasks({}, context);

// Filter the tasks
return allTasks.filter((task) => task.isDone === isDone);
};
Note the changes: 1. We're importing from wasp/server/operations. 2. We've added the context parameter to the getFilteredTasks function. 3. When calling getAllTasks, we're passing an empty object as the first argument (for args) and context as the second argument. The reason your workaround with import { getAllTasks } from "wasp/ext-src/voicehomie/queries"; works is that you're directly importing the implementation, bypassing Wasp's operation handling. However, this approach is not recommended as it doesn't benefit from Wasp's built-in features for operations. Regarding the error in the payment/plans file, it's likely an unrelated issue caused by a missing module. The fix in your queries file doesn't directly address this, but it might have triggered a recompilation that resolved the issue temporarily. For future reference, when working with operations on the server side in Wasp, always remember to: 1. Import from wasp/server/operations 2. Provide the context when calling operations These points are not clearly documented in the current version of the Wasp documentation, as noted in this GitHub issue: Fix docs on calling queries and actions on the server. If you continue to experience issues, you might want to try running wasp clean and then wasp start to ensure all dependencies are correctly installed and compiled, as suggested in this Discord thread: Hey! Any ideas on some solutions to these errors?. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ---------------------- Sorry @Nuno, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist: Perhaps try again in 15mins?
Vinny (@Wasp)
Vinny (@Wasp)4w ago
Did the bot answer your question @Nuno ?
Nuno
NunoOP4w ago
@Vinny (@Wasp) no, adding the context to the function doesn't change anything.
Vinny (@Wasp)
Vinny (@Wasp)4w ago
ok let me reproduce your code real quick
Vinny (@Wasp)
Vinny (@Wasp)4w ago
ok @Nuno it looks like the Wasp operations are always expecting a user object to be passed into it when used this way:
import { testOperation1 } from 'wasp/server/operations';

export const testOperation2 = async (_args, context) => {
const test = await testOperation1({ user: context.user });
return test;
};
import { testOperation1 } from 'wasp/server/operations';

export const testOperation2 = async (_args, context) => {
const test = await testOperation1({ user: context.user });
return test;
};
or another way is just to import the operation from the relative file when using it on the server:
import { testOperation1 } from './operations'; // <--------- import relative path

export const testOperation2: TestOperation<void, void> = async (_args, context) => {

const test = await testOperation1(_args, context);
return test
};
import { testOperation1 } from './operations'; // <--------- import relative path

export const testOperation2: TestOperation<void, void> = async (_args, context) => {

const test = await testOperation1(_args, context);
return test
};
of course when you import the operation on the client, you'll want to use:
import { operation } from 'wasp/client/operations'
import { operation } from 'wasp/client/operations'
here are the relevant docs: https://wasp-lang.dev/docs/data-model/operations/overview Maybe @sodic has some recommendations about what's best here.
Overview | Wasp
While Entities enable you to define your app's data model and relationships, Operations are all about working with this data.
Filip
Filip4w ago
I'll try it out today. It's a weird error in any case. Thanks for the report! Tried it out - this doesn't happen with vanilla Wasp. It's specific to Open Saas. So, @Nuno, what you did in the beginning should work (and does outside of Open Saas). I'll now dig in to see why it's broken in OpenSaas, it's a bug on our side. I'm guessing Open Saas does something that triggers an edge case in Wasp and causes a bug I found out what the issue is, but there's no easy way to fix it. I'll try to get the bugfix out ASAP In short, the issue is caused by server code importing local files without extensions, for example import x from './file' instead of import x from './file.js Technically, Wasp doesn't support importing server-side code without extensions (see #2222), but the error only happens if a user imports something from wasp/server/operations. Since this was so easy to miss, none of OpenSaas's server-side imports include the .js extension - they're all extensionless. I'll try to fix the core issue in Wasp ASAP. Until then, I don't know what the best solution is. @Nuno Technically, you could start adding .js to all the imports Wasp complains about, one by one (but there's a lot). Or, you can structure your code in a way that you don't need to use wasp/server/operations
WWWillems
WWWillems4w ago
@Filip I run into this issue all the time using Wasp, as it's so Wasp specific (having to include the js extension while it's a ts file 🥺). Can't wait for the fix ❤️
Filip
Filip4w ago
@WWWillems What would be your ideal scenario? I'm planning to make it so users should never specify extensions (e.g., improt x from './someModule'). Would this work for you?
WWWillems
WWWillems4w ago
Yep perfect 👌
Filip
Filip4w ago
I've implemented the fix: https://github.com/wasp-lang/wasp/pull/2493 It will probably get reviewed released next week. However, if you guys need the fix urgently, I can hook you up with a special nightly build - just for you 🕵️
Other things may break though, since it hasn't gone through QA yet (but you'll probably be fine) Hey fellas! @WWWillems @Nuno Wasp 0.16.1 that includes this fix is out. You can install it with:
curl -sSL https://get.wasp-lang.dev/installer.sh | sh -s
curl -sSL https://get.wasp-lang.dev/installer.sh | sh -s
And the error should be gone completely. Please let me know if it worked 😄 And thanks for the patience!
WWWillems
WWWillems4w ago
Awesome, thanks for the quick fix!

Did you find this page helpful?