When trying to construct a URL in a Next.js Appwrite project, a "TypeError" may occur, but it works perfectly fine when the URL is provided directly

I am currently following a tutorial on YouTube by JS Mastery about their HealthCare application using Next.js and Appwrite. I have obtained my API keys from the Appwrite cloud and added them to the .env.local file. However, upon running my project, I encounter the following error:

TypeError: Failed to construct 'URL': Invalid URL
    at Users.create (users.mjs:77:17)
    at createUser (patient.actions.ts:6:37)
    at onSubmit (PatientForm.tsx:43:42)
    at eval (index.esm.mjs:2256:23)

The code snippet for creating a user is as follows:

import { ID, Query } from "node-appwrite"
import { users } from "../appwrite.config"

export const createUser = async (user: CreateUserParams) => {
    try {
        const newUser = await users.create(
            ID.unique(), 
            user.email, 
            user.phone, 
            undefined, 
            user.name
        )
        console.log(newUser)

    } catch(error: any) {
        if (error && error?.code === 409) {
            const documents = await users.list([
                Query.equal('email', [user.email])
            ])

            return documents?.users[0]
        } else {
            console.log(error)
        }
    }
}

This segment of code exposes the user:

import * as sdk from "node-appwrite";

export const {
    NEXT_PUBLIC_ENDPOINT: ENDPOINT,
    PROJECT_ID,
    API_KEY,
    DATABASE_ID,
    PATIENT_COLLECTION_ID,
    DOCTOR_COLLECTION_ID,
    APPOINTMENT_COLLECTION_ID,
    NEXT_PUBLIC_BUCKET_ID: BUCKET_ID,
} = process.env;

const client = new sdk.Client();

client.setEndpoint(ENDPOINT!).setProject(PROJECT_ID!).setKey(API_KEY!);

export const databases = new sdk.Databases(client);
export const users = new sdk.Users(client);
export const messaging = new sdk.Messaging(client);
export const storage = new sdk.Storage(client);

Here are the contents of the .env.local file:

PROJECT_ID=************
API_KEY=************************************
DATABASE_ID=************
PATIENT_COLLECTION_ID=************
DOCTOR_COLLECTION_ID=************
APPOINTMENT_COLLECTION_ID=************
NEXT_PUBLIC_BUCKET_ID=************
NEXT_PUBLIC_ENDPOINT=https://cloud.appwrite.io/v1

I have verified that the API values are correct. To further confirm, I attempted substituting the variable names with the actual .env values and everything worked without issues.


client
    .setEndpoint("https://cloud.appwrite.io/v1")
    .setProject("***************")
    .setKey("*****************);

If you have any insights into what might be causing this issue or suggestions on how to resolve it, please do let me know. Any assistance would be greatly appreciated. Thank you.

Link to the YouTube video

Answer №1

I spent a considerable amount of time trying to figure this out. Here's the key addition that helped me break through in patients.actions.ts:

"implement server logic"

Answer №2

Make sure to include the statement "use server" at the top of your patients.actions.ts file. By adding this declaration, you are instructing Next.js to run all functions within this file on the server side only and not on the client side. Server-side code has access to all environment variables, even those that are not specifically prefixed with NEXT_PUBLIC_. This explains why your PROJECT_ID, API_KEY, and DATABASE_ID are now accessible.

 "use server"
    
    import { ID, Query } from "node-appwrite";
    import { users } from "../appwrite.config";

    export const createUser = async (user: CreateUserParams) => {
      try {
        const newuser = await users.create(
          ID.unique(),
          user.email,
          user.phone,
          undefined,
          user.name
        );
      } catch (error: any) {
        if (error && error?.code === 409) {
          const documents = await users.list([Query.equal("email", [user.email])]);
          return documents?.users[0];
        }
        console.error("An error occurred while creating a new user:", error);
      }
    };

Answer №3

After experimenting, I found a solution that worked perfectly for me. Here is the updated configuration:

/** @type {import('next').NextConfig} */
const nextConfig = {
    env: {
        PROJECT_ID: process.env.PROJECT_ID,
        API_KEY:process.env.API_KEY,
        DATABASE_ID:process.env.DATABASE_ID,
        PATIENT_COLLECTION_ID:process.env.PATIENT_COLLECTION_ID,
        DOCTOR_COLLECTION_ID:process.env.DOCTOR_COLLECTION_ID,
        APPOINTMENT_COLLECTION_ID:process.env.APPOINTMENT_COLLECTION_ID,
        BUCKET_ID:process.env.BUCKET_ID,
        ENDPOINT:process.env.ENDPOINT
    }
};

export default nextConfig;

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to achieve the functionality of "redirecting to the previous dynamic route in history after a successful login" with Nextauth?

In an attempt to set up a system where users are redirected to the previous protected dynamic route after a successful login, I will provide a brief explanation. Let's start with the folder structure, Login component, and Nextauth settings: Using &qu ...

Choose the Angular 2 option

I am having an issue with the select option in my code. The person's gender property is assigned 'M' for male, but I need to allow users to change it to 'F' for female. Here is the HTML code snippet: <span > <span &g ...

What are the reasons behind the code not functioning properly while utilizing 'vue-property-decorator' in Vue.js with TypeScript?

I am currently working on a project using Vue.js and TypeScript, but I am facing an issue with 'vue-property-decorator'. I have two code snippets that are supposed to achieve the same result, but only one is working. Can someone please help me id ...

Experimenting with nested dual dynamic routing within the app's directory

Currently working with NextJS 13 and executing the following operations within the app directory. I am attempting to utilize the generateStaticParams function to generate static pages during build time. The route structure is: subpage/[categoryName]/[gif ...

I'm having trouble incorporating TypeScript into my React useState hooks. Can someone help me troubleshoot?

I've been encountering challenges when trying to integrate Typescript into my React code, especially with the useSate hooks. I've dedicated several days to researching how to resolve this issue, but I'm uncertain about what should be passed ...

Reacting to the dynamic removal of spaces

Is there a way to dynamically remove the space between removed chips and older chips in Material-UI when deleting one of them? <div className="row contactsContainer"> {contacts.map((contac ...

The Type '{Property: string, Property2: string} does not match the type Observable<Filters[]>

Here is a method I am trying to use: getFilters(): Observable<Filters[]> { let filters: Observable<Filters[]> = [ { property: "Value", property2: "Value2" }, { property: "Value3", property2: "V ...

Sharing Properties Across Angular Components using TypeScript

Seeking a solution for storing properties needed in multiple components using a config file. For example: number-one-component.ts export class NumberOneComponent { view: any[]; xAxis: number; yAxis: number; label: string; labelPositio ...

How to override or redefine a TypeScript class with generics

Presently, I am immersed in a project involving three.js and TypeScript. It has come to my attention that for organizing elements, the Group class is highly recommended. However, I have noticed that the type definitions for Group do not include a feature l ...

Capturing Input Data Dynamically with Angular Forms

Is there a way to retrieve values from an unknown number of input fields in Angular? This is the code I am using to generate the input fields: <form (ngSubmit)="submit()" #custom="ngModel"> <div *ngIf="let elem of arr"> <input ...

Middleware for Redux in Typescript

Converting a JavaScript-written React app to Typescript has been quite the challenge for me. The error messages are complex and difficult to decipher, especially when trying to create a simple middleware. I've spent about 5 hours trying to solve an er ...

Guide to deploying a Next.js static export using Nginx: Troubleshooting deep link issues

After exporting my Next.js project to the out folder, I noticed a specific folder structure: out index.html terms.html privacy.html To serve these files using nginx, I configured it as follows: server { root /var/www/myproject/out; index index.h ...

I am experiencing difficulties with the state updates, as they are not displaying my products correctly when I select them from

When updating the states setProductsShow and setSelectedCategories, it is important to note that setSelectedCategories is updated before setProductsShow. This sequence is crucial for rendering products correctly. I have come across numerous solutions rega ...

Guide to implementing the collapsible start and stop button feature in Angular

Having an issue in my Angular application with the dashboard page. I've created a button for start or stop (toggle functionality) but it's not working as expected. .component.ts toggleCollapse(jammer) { this.jammer.isCollapsed ? 'START& ...

Tips for creating consistent spacing between elements using Tailwind CSS version 3

I am currently utilizing Tailwind CSS in conjunction with next.js for my project. I have a total of 8 images, each varying in size, and my goal is to display 4 images per row on medium and large devices, while displaying 2 images per row on small devices. ...

Exploring the Benefits of Implementing Google Authentication in the Development

After submitting a verification request to enable a public Google OAuth Client, I had to remove my localhost URIs and callbacks. I've been looking for the most effective way to use Google Auth in development, but haven't come across a definitive ...

Cross-origin error triggered by using an external API within a ReactJS application

I'm facing a common CORS issue in my application while trying to call an API. The API I am attempting to access can be found here: https://github.com/nickypangers/passport-visa-api Below is the code snippet used for making the API call: const getVi ...

Exploring the Functionality of Observables and HTTP Requests in Angular

When I use the http get method in Angular, it returns an observable. To test this, I created a local server that serves up a 50 MB JSON file containing all employee data. import { Injectable } from "@angular/core"; import { Http } from "@angular/http"; im ...

Guide to Integrating BLK Theme into an Angular CLI Project

I've recently set up an Angular project using CLI and I am interested in integrating the BLK theme by Creative Tim into this project. However, the only available option from Creative Tim is to download a pre-existing project and build upon that framew ...

How can I populate dropdown options from an API in a react JS project using typescript and react saga?

Check out my page, where I am trying to fetch brand options from an API. Below is the saga I have implemented: Action.tsx export const getBrandsForDropdown = (request: IPagination) => { return { type: actions, payload: request ...