All Articles

Creating a Reddit Clone Using React and GraphQL - 03

inner peace

This is a series of posts and the previous one you can find from here.

Learning React with Ben Awad — 02

The codebase for this article that can find in here.

rasikag/reddit-clone

We created Post entity. Now we are going to create User entity.

Note:

If we remove @Field() from the entity it will not alow to select that property.

Now, because we are going to create a lot of migration, we are going to add migration command to package.jsonfile.

"create:migration": "mikro-orm migration:create",

running yarn create:migration , create that migration.

But, if you check that migration file, there is no up() method. Because we didn’t add User entity to mikro-orm.config file. After adding re-run the command.

...
// adding User entity in src/mikro-orm.config file.
entities: [Post, User],
...

In our main function we added below code line. Every time the server restart will run the migration.

...
await orm.getMigrator().up();
...

When this is running it will check the migration detail table in the database and it will execute the pending migration scripts.

Now we are going to create Resolver for the user. Make sure that add resolver to the schema.

// src/index.ts
...
resolvers: [HelloResolver, PostResolver, UserResolver],
...

For the user, the register method will take 2 arguments that username and password. We can create a class and use it as a view model. Decorate it with @InputType annotation.

We are not storing the password in plain text. We hash out the password. To do that we are using Argon 2. Use below yarn command to add it.

yarn add argon2

Pro tip from Ben: 
Once you’re in a repository if you see the file with [filename].d.ts you know that it already has the type support. You are good to go.

Okay, we added the code for register user and all set to test it. Here is the GraphQL query to create it. In there you need to pass an object. Please see the structure of the query. register method will take options object as argument.

mutation {
  register(options: {username: "rasikag",password: "rasikag"}) {
    id
    createdAt
    updatedAt
    username
  }
}

One point wants to highlight in here that if you open the docs on register you will see that you will not be getting the password. Because we remove it from a field.

Another point that I want to highlight that we didn’t mention @Arg()type for options . We make it happen implicitly.

@Arg("options") options: UsernamePasswordInput

If the above code not worked, we have explicitly told the type.

@Arg("options", () => UsernamePasswordInput) options: UsernamePasswordInput,

Now we are adding the login function. In here we use @ObjectType annotation. The @ObjectType can use as a return type from mutations.

Now we are defining field error in here. To do that we create another @ObjectType as FieldError.

Okay, now we have the user login. Let’s try this out.

mutation {
  login(options: {username: "rasikag", passward: "rasikag"}){
    errors {
      field
      message
    }
    user {
      id
    username
    }
}

Because we use that UserResponse object, let’s change the register method according to it. Here is the relevant GhraphQL query for it.

mutation {
  register(options: {username: "rasikag", passward: "rasikag"}){
    errors {
      field
      message
    }
    user {
      id
      username
    }
  }
}

If we remove the error handle from below code block and try it out. There is an interesting point need to highlight.

// UserResolver
try {
  await em.persistAndFlush(user);
} catch (err) {
  // comment out the code in here
}

return { user };

We will get an error from GraphQL console that telling,

connot return null for non-nullable field User.id

What will happen there, is it is trying to insert a user and it fails. Then in the last line in will return a user that null but user id is not a nullable field. So the error regarding that.

I will wrap-up this note from here. Soon I will publish the next part of this note.

If you have anything to ask regarding this please leave a comment here. Also, I wrote this according to my understanding. So if any point is wrong, don’t hesitate to correct me. I really appreciate you.

That’s for today friends. See you soon. Thank you.

References:

This article series based on the Ben Award - Fullstack React GraphQL TypeScript Tutorial.

Main image credit