将参数从Electron中的MongoDB API传递到html

ndh0cuux  于 2023-11-15  发布在  Electron
关注(0)|答案(1)|浏览(172)

所以,我正在构建一个个人使用的电子应用程序,我使用MongoDB Atlas作为我的Node应用程序的后端。我是Electron的新手,所以仍然在尝试,所以可能是一个愚蠢的错误。
preload.js

const { contextBridge, ipcRenderer } = require('electron');

process.once("loaded", () => {
    contextBridge.exposeInMainWorld('versions', process.version);
    contextBridge.exposeInMainWorld('engineAPI', {
        userLogin: (...args) => ipcRenderer.invoke('engine:userLogin', ...args).then(result => { console.log(result); return result }),
    });
});

字符串
electron.js

// DEPENDENCIES
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');

// MONGOOSE ADAPATER CALL
const mongooseAdapter = require('../engine/common/mongoose.adapter');

// CONTROLLER CALLS
const userController = require('../engine/controllers/user.controller');

// Create the native Window function to be called within Electron initiation
function createWindow() {
    const mainWindow = new BrowserWindow({
        width: 1366,
        height: 768,
        // Set the path of an additional "preload" script that can be used to
        // communicate between node-land and browser-land.
        webPreferences: {
            preload: path.join(__dirname, "preload.js"),
        },
    });

    mainWindow.loadFile(path.join(__dirname, "./src/pages/index.html"));
    if (!app.isPackaged) {
        mainWindow.webContents.openDevTools();
    }
}

// This method will be called when Electron has finished its initialization and
// is ready to create the browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
    try {
        ipcMain.handle('engine:userLogin', userController.userLogin);
    } catch (error) {
        console.log(error);
    }

    mongooseAdapter.connect(1).then(() => {
        createWindow();
        console.log("Successfully connected to the database");
    }).catch(err => {
        console.log('Not connected. Exiting now...', err);
        process.exit();
    });

    app.on('activate', () => {
        // On macOS it's common to re-create a window in the app when the
        // dock icon is clicked and there are no other windows open.
        if (BrowserWindow.getAllWindows().length === 0) {
            createWindow();
        }
    });
});

// Quit when all windows are closed, except on macOS.
// There, it's common for applications and their menu bar to stay active until
// the user quits  explicitly with Cmd + Q.
app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit();
    }
});

// If your app has no need to navigate or only needs to navigate to known pages,
// it is a good idea to limit navigation outright to that known scope,
// disallowing any other kinds of navigation.
const allowedNavigationDestinations = "https://my-electron-app.com";
app.on("web-contents-created", (event, contents) => {
    contents.on("will-navigate", (event, navigationUrl) => {
        const parsedUrl = new URL(navigationUrl);
        if (!allowedNavigationDestinations.includes(parsedUrl.origin)) {
            event.preventDefault();
        }
    });
});


index.html

<form id="loginForm" onsubmit="handleFormSubmit(event)">
    <div class="form-group">
        <label for="email">Email:</label>
        <input type="email" class="form-control" id="email" name="email" required>
    </div>
    <div class="form-group">
        <label for="password">Password:</label>
        <div class="input-group">
            <input type="password" class="form-control" id="password" name="password" required>
            <div class="input-group-append">
                <button type="button" id="showPassword" class="btn btn-secondary" onclick="togglePasswordVisibility()">Show</button>
            </div>
        </div>
    </div>
    <button type="submit" class="btn btn-primary">Submit</button>
</form>


部分js文件Map到index.html(app.js)

// Function to handle form submission
async function handleFormSubmit(event) {
    event.preventDefault();
    console.log("Hi");
    //Fetching input fields for login creds
    var data = {
        email: document.getElementById("email").value,
        password: document.getElementById("password").value
    };

    const response = await window.engineAPI.userLogin(data);
    console.log(response);
}


Node.js和Mongoose API

const userModel = require('../models/user.model');

exports.userLogin = async (event, args) => {
    try {
        userModel.findOne({ email: args.email }).then(userData => {
            console.log(userData);
            return userData
        }).catch(error => console.log(error));
    } catch (error) {
        console.log(error)
    };
};


当在Node.js API中调用时,此API在日志中返回正确的值。然而,当我试图从调用API的app.js文件中读取相同的值时,它是未定义的。
我错过了什么?提前感谢!

编辑1:添加了下面的mongoose适配器代码:

// CONFIG CALL
const config = require('../../private/config');

// DEPENDENCIES
const mongoose = require('mongoose');

module.exports = {
    connect: function (flag) {
        switch (flag) {
            case 1:
                return new Promise(async (resolve, reject) => {
                    try {
                        const connection = await mongoose.connect(config.dbUrl).catch(error => reject(error));
                        resolve(connection);
                    } catch (error) {
                        reject(error)
                    }
                })
            default:
                break;
        }
    }
}

hwamh0ep

hwamh0ep1#

得到了答案,当你想到它的时候,你会觉得很愚蠢。
问题出在Node的javascript行为上。我在Node.js API中添加了一个await结构,并删除了promise。
更新了下面的代码,供大家参考:
Node.js API

const userModel = require('../models/user.model');
const CryptoJS = require('crypto-js');

exports.userLogin = async (event, args) => {
    try {
        const userData = await userModel.findOne({ email: args.email }).catch(error => console.log(error));
        return userData
    } catch (error) {
        console.log(error)
    };
};

字符串
preload.js

const { contextBridge, ipcRenderer } = require('electron');

process.once("loaded", () => {
    contextBridge.exposeInMainWorld('versions', process.version);
    contextBridge.exposeInMainWorld('engineAPI', {
        userLogin: (...args) => ipcRenderer.invoke('engine:userLogin', ...args),
    });
});

相关问题