How to call module with object Parameter in main file Index.js - javascript

I need to call module from main index.js File
Here is my module
const request = require('./rq.js');
const callback = require('./callback.js')
const url = `https://localhost.3000/${id}`;
request(url, callback)
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
})
module.exports = page; //Tell me how to export all code from module
So here is my index.js file
const Methods = {
page: require('./page.js'),
}
module.exports = //What i need to code here?
File from what i give a call a module :
const main = require('./index.js');
main.page({id: 'id'})
.then(console.log);
So what I should change to call page.js file like that ?

Make the following changes to page.js since in your main file you expect a promise to be returned.
const request = require('./rq.js');
const callback = require('./callback.js')
function page({id}) {
const url = `https://localhost.3000/${id}`;
return request(url, callback)
}
module.exports = {page: page} //Tell me how to export all code from module
Make the following changes to Mehods.js
const Methods = {
page: require('./page.js').page,
}
module.exports = Methods;
Check if this works.

Related

Sveltekit Error: `page` in `load` functions has been replaced by `url` and `params`

I am trying to display my date from GraphCMS in my blog application. I receive this error when I go to my single post link (http://localhost:3000/posts/union-types-and-sortable-relations)
"
page in load functions has been replaced by url and params
Error: page in load functions has been replaced by url and params
"
Here is my code
<script context='module'>
export const load = async ({fetch, page: {params}}) => {
const {slug} = params
const res = await fetch(`/posts/${slug}.json`)
if(res.ok) {
const {post} = await res.json()
return {
props: {post},
}
}
}
</script>
<script>
export let post
</script>
<svelte:head>
<title>Emrah's Blog | Welcome</title>
</svelte:head>
<pre>{JSON.stringify(post, null, 2)}</pre>
Can you please help. Thanks
Try using params instead of page: params, though the latter still works in Sveltekit 278 (which I'm using).
Besides, I'm curious to know what makes you prefer this method to querying GraphCMS for your single post. I do it like this:
import {client} from '$lib/js/graphql-client'
import {projectQuery} from '$lib/js/graphql-queries'
export const load = async ({ params }) => {
const {slug} = params
const variables = {slug}
const {project} = await client.request(projectQuery, variables)
return {
props: {
project
}
}
}
Yes, this has been changed a while ago, now the different parts of what used to be page are passed directly into the load function:
export async function load({ fetch, page }) {
const { params, url } = page
}
export async function load({ fetch, params, url }) {
}
Something else to consider is that now there are page endpoints, if your file is [slug].svelte you can make a file [slug].js and add the following:
export async function get({ params }) {
const { slug } = params;
const post = {}; // add the code to fetch from GraphCMS here
return {
status: 200,
body: {
post
}
}
}
With this you can remove the load function and make your code simpler (especially because you technically already have all this code in your /posts/[slug].json.js file.
<script context='module'>
export async function load({ fetch, params}){
let id = params.users
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`)
const user = await response.json()
if(response.ok){
return {props:{user}}
}
return {
status: response.status,
error : new Error(" sorry no user found")
}
}
export let user

How to mock fs module together with unionfs?

I have written a test case that successfully load files into virtual FS, and at the same time mounted a virtual volume as below
describe("should work", () => {
const { vol } = require("memfs");
afterEach(() => vol.reset());
beforeEach(() => {
vol.mkdirSync(process.cwd(), { recursive: true });
jest.resetModules();
jest.resetAllMocks();
});
it("should be able to mock fs that being called in actual code", async () => {
jest.mock("fs", () => {
return ufs //
.use(jest.requireActual("fs"))
.use(createFsFromVolume(vol) as any);
});
jest.mock("fs/promises", () => {
return ufs //
.use(jest.requireActual("fs/promises"))
.use(createFsFromVolume(vol) as any);
});
const { createFsFromVolume } = require("memfs");
const { ufs } = require("unionfs");
const { countFile } = require("../src/ops/fs");
vol.fromJSON(
{
"./some/README.md": "1",
"./some/index.js": "2",
"./destination": null,
},
"/app"
);
const result = ufs.readdirSync(process.cwd());
const result2 = ufs.readdirSync("/app");
const result3 = await countFile("/app");
console.log({ result, result2, result3 });
});
});
By using ufs.readdirSync, I can access to virtual FS and indeed result giving me files that loaded from disc into virtual FS, result2 representing /app which is a new volume created from vol.fromJSON.
Now my problem is I am unable to get the result for result3, which is calling countFile method as below
import fsPromises from "fs/promises";
export const countFile = async (path: string) => {
const result = await fsPromises.readdir(path);
return result.length;
};
I'm getting error
Error: ENOENT: no such file or directory, scandir '/app'
which I think it's because countFile is accessing the actual FS instead of the virtual despite I've had jest.mock('fs/promises')?
Please if anyone can provide some lead?
This is the function you want to unit test.
//CommonJS version
const fsPromises = require('fs/promises');
const countFile = async (path) => {
const result = await fsPromises.readdir(path);
return result.length;
};
module.exports = {
countFile
}
Now, how you would normally go about this, is to mock fsPromises. In this example specifically readdir() since that is the function being used in countFile.
This is what we call: a stub.
A skeletal or special-purpose implementation of a software component, used to develop or test a component that calls or is otherwise dependent on it. It replaces a called component.
const {countFile} = require('./index');
const {readdir} = require("fs/promises");
jest.mock('fs/promises');
beforeEach(() => {
readdir.mockReset();
});
it("When testing countFile, given string, then return files", async () => {
const path = "/path/to/dir";
// vvvvvvv STUB HERE
readdir.mockResolvedValueOnce(["src", "node_modules", "package-lock.json" ,"package.json"]);
const res = await countFile(path);
expect(res).toBe(4);
})
You do this because you're unit testing. You don't want to be dependent on other functions because that fails to be a unit test and more integration test. Secondly, it's a third-party library, which is maintained/tested by someone else.
Here is where your scenario applies. From my perspective, your objective isn't to test countFile() rather, to test fsPromises and maybe test functionality to read virtual file-systems: unionfs. If so then, fsPromises doesn't need to really be mocked.

import async function from the module

I have a function that looks like this
let fileCache = {};
async function generateFromFile(fullPath) {
if (!fileCache[fullPath]) {
let jsonResource = await fs.readFile(fullPath);
fileCache[fullPath] = JSON.parse(jsonResource);
}
return fileCache[fullPath];
}
When I use it in the same module like this
await generateFromFile('myfile.json');
it works fine.
I created a separate file, put the function there and exported it like this
let fileCache = {};
async function generateFromFile(fullPath) {
if (!fileCache[fullPath]) {
let jsonResource = await fs.readFile(fullPath);
fileCache[fullPath] = JSON.parse(jsonResource);
}
return fileCache[fullPath];
}
module.exports = {
generateFromFile: generateFromFile
}
I imported it like this
const utils = require('../util/utils.js');
and wanted to use like await utils.generateFromFile('myfile.json'); but it fails with the error
TypeError [ERR_INVALID_CALLBACK]: Callback must be a function. Received undefined
What is the problem?
How did you import your fs module. To use readFile with await your should
either write fs.promise.readFile
or import fs as
import { promises as fs } from 'fs'
Are you sure that your newly created file is in the relative directory ../util/utils.js? Your export looks fine. Maybe try to print out the imported utils object to see what you actually imported.
EDIT: You are also passing relative filenames to your function which is now in a different diretory than before. When accessing fs.readFile(fullPath) it tries to read the file inside the directory "util/". You should call your function with a full filepath like util.generateFromFile(path.join(__dirname, "myfile.json")) using the path node package.
EDIT 2: Like Raeesaa state you are using fs.readFile wrong. It does not return a Promise but expects a callback. To is it with await you have to promisify it like so:
const fs = require("fs");
const { promisify } = require("util");
const readFileAsync = promisify(fs.readFile);
let fileCache = {};
async function generateFromFile(fullPath) {
if (!fileCache[fullPath]) {
let jsonResource = await readFileAsync(fullPath);
fileCache[fullPath] = JSON.parse(jsonResource);
}
return fileCache[fullPath];
}
module.exports = {
generateFromFile: generateFromFile
}
EDIT 3: If you only import JSON files you can do it by using require. Internally, require has also a cache so imports are only executed once. You can import JSON files as objects like so: const obj = require("myfile.json");

Configuring Cypress.env() variable to an imported module file

I'm trying to set & config a new env variable in Cypress.io. In the file cypress/plugins/index.js, I have imported another file like so:
const { getBranch } = require('path/to/file/goes/here/getBranch');
Then, I'm trying to set the new env variable like so:
// cypress/plugins/index.js
module.exports = (on, config) => {
terminalReport.installPlugin(on);
const configuration = config;
configuration.env.injectMainBranchId = getBranch('develop');
// more code below...
However, this is not working. However, if I hardcode the value it does work:
configuration.env.injectMainBranchId = 'develop';
You see the result in the screenshot below:
This is the dummy content of getBranch module:
const getBranch = branch => {
return branch;
};
module.export = { getBranch };
What am I doing wrong?
Typo in getBranch:
const getBranch = branch => {
return branch;
};
module.export = { getBranch };
export should be changed to exports

Why I use params in getInitialProps they are undefined when build in Next.js

I have this problem in Next.js. I call the API in getInitialProps and pass the params to my components then it works when I use it in mu project. But when I want to build it gives me error that the params are undefined.
This is how I call my API and pass it to component:
import BlogItem from './blogItem'
import axios from 'axios'
import { withRouter } from 'next/router'
import { APIURL, replaceAll } from '../../../components/config'
const Post = (props) => {
return (
<BlogItem
services ={props.services }
/>
)
}
Post.getInitialProps = async ({ query }) => {
const id = query.id
const urlTitle = encodeURI(query.title)
const services = null;
try {
const response = await axios.get(`${APIURL}getservice`);
services = response.data.response.posts;
} catch (err) {
console.error(err)
}
return {
services
}
}
export default withRouter(Post)
It seems that you defined services as a const that contain null! the whole code seems fine. Try changing const to let:
Post.getInitialProps = async ({ query }) => {
const id = query.id
const urlTitle = encodeURI(query.title)
let services = null; //this line
try {
const response = await axios.get(`${APIURL}getservice`);
services = response.data.response.posts;
} catch (err) {
console.error(err)
}
console.log(services) //you should have the data right here
return {services}
}
Example :
Look at this example. Run it and navigate to /about page :
You need to make sure that your url params are passed into the querystring on the server, In your case, something like this:
server.get('/page/:uid/:id', (req, res) => {
const mergedQuery = Object.assign({}, req.query, req.params)
return app.render(req, res, '/page', mergedQuery);
})
Then your getInitialProps can get them straight from the query, regardless of where it loads.

Categories

Resources