Creating a mutation component - graphql

I am trying to create a graphql mutation component. My goal is to be able to import it and call registerUser(userInfo) to run and execute my mutation.
const registerUser = (user) => {
const REGISTER_USER = gql`
mutation RegisterUser($email: String!, $password: String!, $username: String!){
RegisterUser(email: $email, password: $password, username: $username){
id
username
email
}
}
`
const variables = {
email: user.email,
password: user.password,
username: user.username,
};
return (
<Mutation mutation={REGISTER_USER} variables={variables}>
{(registerUser, { error, data }) => {
if (error) console.log('error', error);
if (data) console.log('data', data);
registerUser()
}}
</Mutation>
)
}
export default registerUser;

Related

How to create objects(like in JS) in AWS appsync resolvers?

I am trying to create this scenario in my resolvers file:
let { data } = await context.client.post(
`https://myendpoint.com/api?action=getUserApiKey&user=${user}&password=${password}&2faCode=${secondFactorToken}`,
);
var userData = {
username: data.user.username,
email: data.user.email,
name: data.user.name,
userId: data.user.userId,
avatarUrl: data.user.avatarUrl,
};
var params = {
key: data.apiKey,
user: userData,
};
return params;
to this in my appsync resolvers:
#if($ctx.result.statusCode == 200)
#set($userData={
$username: $ctx.result.username,
$email: $ctx.result.email,
$name: $ctx.result.name,
$userId: $ctx.result.userId,
$avatarUrl: $ctx.result.avatarUrl,
})
#set($params = {
$key: $ctx.result.apiKey,
$user: $userData,
})
$util.toJson($params);
#else
$utils.appendError($ctx.result.body, "$ctx.result.statusCode")
#end
What will be the right syntax to perform this in appsync?

Post Error with Apollo Client While Creating a New User

I am running into a POST http://localhost:4000/ 400 (Bad Request) Error.
I am trying to create a new user with the following frontend.
const REGISTER_USER = gql`
mutation Mutation(
$createUser: CreateUserInput!
) {
createUser(createUserInput: $createUserInput){
email
name
token
password
}
}
`
const Register = () => {
const context = useContext(AuthContext)
let navigate = useNavigate()
const [errors, setErrors] = useState([])
function registerUserCallback() {
console.log("Callback hit")
registerUser()
}
const {onChange, onSubmit, values} = useForm(registerUserCallback, {
name: '',
email: '',
password:'',
confirmPassword: '',
})
const [registerUser, {loading}] = useMutation(REGISTER_USER, {
update(proxy, {data: {registerUser: userData}}) {
context.login(userData)
navigate('/Dashboard')
},
onError({graphQLErrors}) {
setErrors(graphQLErrors)
console.log("Error: " + graphQLErrors)
console.log(graphQLErrors)
},
variables: {createUserInput: values}
})
However, the grapQLErrors is not even being console.logged for some reason. When I run the Mutation via Apollo Studio it works. Any information would be great!
Edit: Network Tab Screenshot:
Adding Code for my httpLink:
import { ApolloClient, InMemoryCache, createHttpLink } from "#apollo/client";
import { setContext } from "#apollo/client/link/context";
const httpLink = createHttpLink({
uri: 'http://localhost:4000'
})
const authLink = setContext((_, {headers}) => {
return {
headers: {
...headers,
authorization: localStorage.getItem('token') || ""
}
}
})
export const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});
Edit: createUser Mutation seems to be the issue. This is the Network response error: ["GraphQLError: Unknown argument "createUserInput" on field "Mutation.createUser".","
#Mutation((returns) => User)
async createUser(#Arg('data') data:CreateUserInput, #Ctx() ctx: Context) {
const oldUser = await ctx.prisma.user.findFirst({ where: { email: data.email}})
if(oldUser) {
throw new ApolloError('A user is already registered with the email' + data.email, 'USER_ALREADY_EXISTS')
}
var encryptedPassword = await bcrypt.hash(data.password, 10)
const newUser = await ctx.prisma.user.create({
data: {
name: data.name,
email: data.email,
password: encryptedPassword
}
})
return {token: jwt.sign(newUser, 'supersecret')}
}
Here is a screen shot of my Preview in my Network...I really don't get it.
export class CreateUserInput {
#Field((type) => String)
name: string
#Field((type) => String)
email: string
#Field((type) => String)
password: string

Apollo-client graphql localstate management setup

I'm sitting for 2 days trying to get my setup right. My target is Next.js with ApolloGraphQl for Database request as well as local state management handling.
My problem is the setup for the local state management. Don't know why i'm unable to correctly get it to work. I hope you can help me out.
I pushed my actual status of the project on github using the following repo:
https://github.com/Maetes/apollo-next-local
UPDATE:
it is fine to query and mutate the state when i just call the cache object itself so all is fine. But when i try to trigger a resolver, nothing happens. I'ts like the Apollo-client does not see the typedefs and resolvers.
Here is my useApollo Hook with Client init:
import { IncomingMessage, ServerResponse } from 'http';
import { useMemo } from 'react';
import { ApolloClient } from 'apollo-client';
import { InMemoryCache, NormalizedCacheObject } from 'apollo-cache-inmemory';
import { resolvers } from './localResolvers';
import { typeDefs } from './localTypeDefs';
import {
CREATE_USER,
GET_CURRENT_USER,
SET_CURRENT_USER,
ALL_USERS,
} from './localDocuments';
let apolloClient: ApolloClient<NormalizedCacheObject> | undefined;
export type ResolverContext = {
req?: IncomingMessage;
res?: ServerResponse;
};
function createIsomorphLink(context: ResolverContext = {}) {
if (typeof window === 'undefined') {
const { SchemaLink } = require('apollo-link-schema');
const { schema } = require('../pages/api/index');
return new SchemaLink({ schema, context });
} else {
const { HttpLink } = require('apollo-link-http');
return new HttpLink({
uri: 'http://localhost:3000/api',
credentials: 'same-origin',
});
}
}
function createApolloClient(context?: ResolverContext) {
let cache = new InMemoryCache();
cache.writeData({
data: {
currentUser: {
__typename: 'CurrentUser',
email: '',
nachname: '',
title: '',
id: '',
},
},
});
let client = new ApolloClient({
ssrMode: typeof window === 'undefined',
link: createIsomorphLink(context),
cache: cache,
typeDefs,
resolvers,
});
// client.writeData({
// data: {
// currentUser: {
// __typename: 'CurrentUser',
// email: '',
// nachname: '',
// title: '',
// id: '',
// },
// },
// });
return client;
}
export function initializeApollo(
initialState: any = null,
// Pages with Next.js data fetching methods, like `getStaticProps`, can send
// a custom context which will be used by `SchemaLink` to server render pages
context?: ResolverContext
) {
const _apolloClient = apolloClient ?? createApolloClient(context);
// If your page has Next.js data fetching methods that use Apollo Client, the initial state
// get hydrated here
if (initialState) {
_apolloClient.cache.restore(initialState);
}
// For SSG and SSR always create a new Apollo Client
if (typeof window === 'undefined') return _apolloClient;
// Create the Apollo Client once in the client
if (!apolloClient) apolloClient = _apolloClient;
return _apolloClient;
}
export function useApollo(initialState: any) {
const store = useMemo(() => initializeApollo(initialState), [initialState]);
return store;
}
This is my typedef file:
import gql from 'graphql-tag';
export const typeDefs = gql`
extend type Query {
getCurrentUser: CurrentUser!
}
type CurrentUser {
email: String!
nachname: String!
title: String!
id: ID!
__typename: String!
}
extend type Mutation {
setCurrentUser(
email: String!
nachname: String!
title: String!
id: ID!
): CurrentUser!
}
`;
this are my resolvers:
import { InMemoryCache } from 'apollo-cache-inmemory';
import { GET_CURRENT_USER } from './localDocuments';
export const resolvers = {
CurrentUser: {
currentUser: (_: {}, { cache }: { cache: InMemoryCache }) => {
console.log('Resolver Query triggered');
// const { user }: any = cache.readQuery({
// query: GET_CURRENT_USER,
// });
const data: any = {};
data.__typename = 'CurrentUser';
return data;
},
getCurrentUser: (_: {}, { cache }: { cache: InMemoryCache }) => {
console.log('Resolver Query triggered');
// const { user }: any = cache.readQuery({
// query: GET_CURRENT_USER,
// });
const data: any = {};
data.__typename = 'CurrentUser';
return data;
},
},
Query: {
getCurrentUser: (_: {}, { cache }: { cache: InMemoryCache }) => {
console.log('Resolver Query triggered');
// const { user }: any = cache.readQuery({
// query: GET_CURRENT_USER,
// });
const data: any = {};
data.__typename = 'CurrentUser';
return data;
},
currentUser: (_: {}, { cache }: { cache: InMemoryCache }) => {
console.log('Resolver Query triggered');
// const { user }: any = cache.readQuery({
// query: GET_CURRENT_USER,
// });
const data: any = {};
data.__typename = 'CurrentUser';
return data;
},
},
Mutation: {
setCurrentUser: (
_: {},
variables: any,
{ cache }: { cache: InMemoryCache }
) => {
const { currentUser }: any = cache.readQuery({ query: GET_CURRENT_USER });
console.log('mutationResolver Triggered');
console.log(
'olduser',
currentUser.email,
currentUser.nachname,
currentUser.title
);
const newUser = {
email: variables.email,
title: variables.title,
nachname: variables.nachname,
__typename: 'CurrentUser',
};
console.log('newUser', newUser);
const erg = cache.writeQuery({
query: GET_CURRENT_USER,
data: newUser,
});
return newUser;
},
},
};
And finaly my Document file for individual input. Please note in the GetCurrentUserQuery query when i change "getCurrentUser" to "currentUser" all is working fine cause apollo targets the raw object itself.
import gql from 'graphql-tag';
//Server
export const ALL_USERS = gql`
query allUsersQuery {
allUsers {
title
nachname
email
id
__typename
}
}
`;
//client
export const GET_CURRENT_USER = gql`
query GetCurrentUserQuery {
getCurrentUser #client(always: true) {
email
nachname
title
__typename
}
}
`;
//Client
export const SET_CURRENT_USER = gql`
mutation SetCurrentUserMutation(
$email: String!
$nachname: String!
$title: String!
$id: String!
) {
setCurrentUser(email: $email, nachname: $nachname, title: $title) #client {
email
title
nachname
id
__typename
}
}
`;
//Server
export const CREATE_USER = gql`
mutation CreateUserMutation(
$email: String!
$nachname: String!
$title: String!
$password: String!
) {
createUser(
email: $email
nachname: $nachname
title: $title
password: $password
) {
__typename
email
nachname
title
password
id
}
}
`;

Apollo Client Mutation get an error 400 with React Component

Mutation gql tag:
// AppAdminLoinInput is wrong spell don't focus it.
const LOGIN_MUTATION = gql`
mutation AppAdminLoinInput($email: String!, $password: String!) {
appAdminLogin(email: $email, password: $password) {
name
email
token {
accessToken
refreshToken
}
}
}
`;
Mutation Function onSubmit
onSubmitLogin = async (e, appAdminLogin) => {
const { email, password } = this.state;
e.preventDefault();
if (!validator.isEmail(email)) {
console.log("Not email format");
return;
}
if (password.length < 8) {
return;
}
appAdminLogin({
variables: {
email,
password
}
});
};
When onSubmitLogin do i get an error 400 (Bad request)
What am i do wrong?
sorry about my english skill xD

React Apollo 2.1 mock schema error

I'm trying to provide a mock schema to a component using React Apollo 2.1. However, it returns this error.
Error: Network error: No more mocked responses for the query: {
me {
id
email
username
first_name
last_name
bio
website
}
}
, variables: {}
at new ApolloError (ApolloError.js:43)
at ObservableQuery.currentResult (ObservableQuery.js:107)
at Query._this.getQueryResult (react-apollo.browser.umd.js:319)
at Query.render (react-apollo.browser.umd.js:421)
at finishClassComponent (react-dom.development.js:8389)
at updateClassComponent (react-dom.development.js:8357)
at beginWork (react-dom.development.js:8982)
at performUnitOfWork (react-dom.development.js:11814)
at workLoop (react-dom.development.js:11843)
at renderRoot (react-dom.development.js:11874)
How did you add mock functionality on React Apollo 2.1? I tried searching the solutions but both information for older versions and newer ones and couldn't resolve this.
Here's the code.
index.stories.js
import React from 'react';
import { storiesOf } from '#storybook/react';
import { action } from '#storybook/addon-actions';
import { makeExecutableSchema, addMockFunctionsToSchema } from 'graphql-tools';
import gql from 'graphql-tag'
import { MemoryRouter } from 'react-router';
import { MockedProvider } from 'react-apollo/test-utils';
import { buildMockedClient } from '../../../mockedApolloClient';
import AccountSettings from './index';
const typeDefs = `
interface User {
id: ID!,
email: String!,
username: String,
first_name: String,
last_name: String,
bio: String,
website: String
}
type Student implements User {
id: ID!,
email: String!,
username: String,
first_name: String,
last_name: String,
bio: String,
website: String
}
type InputError {
key: String!
message: String!
}
type UserResult {
errors: InputError,
user: User
}
input UpdateAccountInput {
first_name: String
last_name:String
email: String
username: String
bio: String
website: String
}
type Query {
me: User
}
type Mutation {
updateAccount(params: UpdateAccountInput!): UserResult!
}
`
const typeResolvers = {
User: {
__resolveType(data) {
return data.__typename // typename property must be set by your mock functions
}
}
}
const me = {
id: () => 1,
email: () => 'testuser#test.jp',
username: () => 'hiro1107',
first_name: () => 'Atsuhiro',
last_name: () => 'Teshima',
bio: () => 'test',
website: () => 'https://www.test.jp',
}
const schema = makeExecutableSchema({
typeDefs,
typeResolvers
})
const mocks = {
User: () => ({
id: () => 1,
email: () => 'testuser#codegrit.jp',
username: () => 'hiro1107',
first_name: () => 'Atsuhiro',
last_name: () => 'Teshima',
bio: () => 'test',
website: () => 'https://www.codegrit.jp',
__typename: () => 'Student'
}),
Query: () => ({
me: () => me
})
}
addMockFunctionsToSchema({
schema,
mocks,
preserveResolvers: false
});
storiesOf('Account Settings', module)
.addDecorator(story => (
<MockedProvider client={mockedClient} mocks={mocks} >
<MemoryRouter initialEntries={['/']}>{story()}</MemoryRouter>
</MockedProvider>
))
.add('With Mock', () => (
<AccountSettings />
));
const mockedClient = buildMockedClient(schema);
storiesOf('Account Settings', module)
.addDecorator(story => (
<MockedProvider client={mockedClient} mocks={mocks} >
<MemoryRouter initialEntries={['/']}>{story()}</MemoryRouter>
</MockedProvider>
))
.add('With Mock', () => (
<AccountSettings />
));
mockedApolloClient.js
import { ApolloClient } from 'apollo-client';
import { SchemaLink } from 'apollo-link-schema';
import { InMemoryCache } from 'apollo-cache-inmemory';
const apolloCache = new InMemoryCache(window.__APOLLO_STATE__);
export function buildMockedClient(schema) {
return new ApolloClient({
cache: apolloCache,
link: new SchemaLink({ schema })
})
}
package.json
"apollo-cache-inmemory": "^1.1.9",
"apollo-client": "^2.2.5",
"apollo-link-context": "^1.0.7",
"apollo-link-http": "^1.5.2",
"apollo-link-schema": "^1.1.0",
"graphql": "^0.13.1",
"graphql-tag": "^2.8.0",
"graphql-tools": "^2.24.0",
"react": "^16.3.1",
"react-apollo": "^2.1.0",
"react-dom": "^16.3.1",
I found out that I need to use ApolloProvider instead MockedProvider.
So, this code will work.
import React from 'react';
import { storiesOf } from '#storybook/react';
import { action } from '#storybook/addon-actions';
import { makeExecutableSchema, addMockFunctionsToSchema } from 'graphql-tools';
import gql from 'graphql-tag'
import { MemoryRouter } from 'react-router';
import { ApolloProvider, Query } from 'react-apollo';
import { buildMockedClient } from '../../../mockedApolloClient';
import AccountSettings from './index';
const typeDefs = `
type Query {
me: User!
}
type Mutation {
updateAccount(params: UpdateAccountInput!): UserResult!
}
interface User {
id: ID!,
email: String!,
username: String,
first_name: String,
last_name: String,
bio: String,
website: String
}
type Student implements User {
id: ID!,
email: String!,
username: String,
first_name: String,
last_name: String,
bio: String,
website: String
}
type InputError {
key: String!
message: String!
}
type UserResult {
errors: InputError,
user: User
}
input UpdateAccountInput {
first_name: String
last_name:String
email: String
username: String
bio: String
website: String
}
`
const typeResolvers = {
User: {
__resolveType(data) {
return data.__typename()
}
}
}
const mocks = {
User: () => ({
id: () => 1,
email: 'testuser#codegrit.jp',
username: 'hiro1107',
first_name: 'Atsuhiro',
last_name: 'Teshima',
bio: 'test',
website: 'https://www.test.jp',
__typename: 'Student',
}),
Student: () => ({
id: () => 1,
email: 'testuser#test.jp',
username: 'hiro1107',
first_name: 'Atsuhiro',
last_name: 'Teshima',
bio: 'test',
website: 'https://www.test.jp',
__typename: () => 'Student'
}),
query: () => ({
me: () => ({
id: () => 1,
email: 'testuser#test.jp',
username: 'hiro1107',
first_name: 'Atsuhiro',
last_name: 'Teshima',
bio: 'test',
website: 'https://www.test.jp',
__typename: () => 'Student'
})
})
}
const schema = makeExecutableSchema({
typeDefs,
resolvers: typeResolvers
})
addMockFunctionsToSchema({
schema,
mocks,
preserveResolvers: true
});
const client = buildMockedClient(schema);
const userQuery = gql`
query {
me {
id
email
username
first_name
last_name
bio
website
}
}
`
storiesOf('Account Settings', module)
.addDecorator(story => (
<ApolloProvider client={client} >
<MemoryRouter initialEntries={['/']}>{story()}</MemoryRouter>
</ApolloProvider>
))
.add('With Mock', () => (
<AccountSettings />
));

Resources