I have this issue after updating to apollo-server-lambda@3^
“Error: Unable to determine event source based on event.”
This code used to work a while ago but since the version 3^ of apollo-server-lambda my code is breaking and gives me the error message above…
This is my netlify back-end function code: (graphql.js)
const {
ApolloServerPluginLandingPageGraphQLPlayground,
// ApolloServerPluginLandingPageDisabled,
} = require('apollo-server-core');
const faunadb = require('faunadb');
const q = faunadb.query;
const client = new faunadb.Client({ secret: process.env.GATSBY_FAUNADB });
const typeDefs = gql`
type Query {
todos: [Todo]!
}
type Todo {
id: ID!
text: String!
done: Boolean!
}
type Mutation {
addTodo(text: String!): Todo
updateTodoDone(id: ID!): Todo
}
`;
const resolvers = {
Query: {
todos: async (parents, args, { user }) => {
if (!user) {
return [];
}
const results = await client.query(
q.Paginate(q.Match(q.Index('todos_by_user'), user)),
);
return results.data.map(([ref, text, done]) => ({
id: ref.id,
text,
done,
}));
},
},
Mutation: {
addTodo: async (_, { text }, { user }) => {
if (!user) {
throw new Error('voer ieks goeds in man');
}
const results = await client.query(
q.Create(q.Collection('todos'), {
data: { text, done: false, owner: user },
}),
);
return {
...results.data,
id: results.ref.id,
};
},
updateTodoDone: async (_, { id }, { user }) => {
if (!user) {
throw new Error('voer ieks goeds in man ali boalowii');
}
const results = await client.query(
q.Update(q.Ref(q.Collection('todos'), id), { data: { done: true } }),
);
return {
...results.data,
id: results.ref.id,
};
},
},
};
console.log('CLIENT grapqhl #mnfx', client);
// const apolloHandler = server.createHandler();
exports.handler = async (event, context) => {
try {
const server = new ApolloServer({
typeDefs,
resolvers,
context: async () => {
// console.log('ff checken event', event);
console.log('ff checken context', context);
if (context.clientContext.user) {
return {
event,
context,
user: context.clientContext.user.sub,
};
}
return {};
},
// playground
playground: [ApolloServerPluginLandingPageGraphQLPlayground()],
introspection: true,
});
const apolloHandler = server.createHandler({
expressGetMiddlewareOptions: {
cors: {
origin: '*',
credentials: true,
},
},
});
console.log('before event ish:', event);
console.log('before context ish:', context);
return await apolloHandler(event, context);
} catch (err) {
return console.error('Failed ISH!', err);
}
};
This is the wrapper file: (gatsby-browser.js)
/* eslint-disable prettier/prettier */
/* eslint-disable react/jsx-props-no-spreading */
const React = require('react');
const {
ApolloProvider,
ApolloClient,
HttpLink,
InMemoryCache,
} = require('@apollo/client');
require('bootstrap/dist/css/bootstrap.min.css');
const netlifyIdentity = require('netlify-identity-widget');
const { setContext } = require('@apollo/client/link/context');
// const fetch = require('isomorphic-fetch');
const fetch = require('cross-fetch');
// const fetch = require('node-fetch');
const { IdentityProvider } = require('./src/context/identity-context');
const Layout = require('./src/components/layout').default;
const authLink = setContext((_, { headers }) => {
const user = netlifyIdentity.currentUser();
const token = user.token.access_token;
console.log('HEADERS @ gatsby-browser #mnfx:', headers);
console.log('USER @ gatsby-browser #mnfx:', user);
console.log('TOKEN @ gatsby-browser #mnfx:', token);
return {
headers: {
...headers,
Authorization: token ? `Bearer ${token}` : '',
},
};
});
const httpLink = new HttpLink({
fetch,
uri: 'https://afrodiasphere.netlify.app/.netlify/functions/graphql',
});
const client = new ApolloClient({
ssrMode: true,
cache: new InMemoryCache(),
link: authLink.concat(httpLink),
});
const wrapPageElement = ({ element, props }) => (
<Layout {...props}>{element}</Layout>
);
exports.wrapPageElement = wrapPageElement;
const wrapRootElement = ({ element }) => (
<ApolloProvider client={client}>
<IdentityProvider>{element}</IdentityProvider>
</ApolloProvider>
);
exports.wrapRootElement = wrapRootElement;
// export const onPreRouteUpdate = ({ location, prevLocation }) => {
// console.log('new pathname', location.pathname);
// console.log('old pathname', prevLocation ? prevLocation.pathname : null);
// };
And to make it complete, also the front-end page: (dashboard.tsx)
import React, { useContext, useRef } from 'react';
import { gql, useMutation, useQuery } from '@apollo/client';
import { Button, Form, ListGroup, InputGroup } from 'react-bootstrap';
import IdentityContext from '../context/identity-context';
// interface Props {}
const ADD_TODO = gql`
mutation AddTodo($text: String!) {
addTodo(text: $text) {
id
}
}
`;
const UPDATE_TODO_DONE = gql`
mutation UpdateTodoDone($id: ID!) {
updateTodoDone(id: $id) {
text
done
}
}
`;
const GET_TODOS = gql`
query GetTodos {
todos {
id
text
done
}
}
`;
const Dashboard = () => {
const { user, identity: netlifyIdentity } = useContext(IdentityContext);
const inputRef = useRef();
const [addTodo] = useMutation(ADD_TODO);
const [updateTodoDone] = useMutation(UPDATE_TODO_DONE);
const { loading, error, data, refetch } = useQuery(GET_TODOS);
console.log(data);
// console.log('displatch! :', dispatch, 'data! :', data);
return (
<div>
<span>Hallo {user && user.user_metadata.full_name}, welkom!</span>
{user && (
<Button
variant="outline-danger"
type="button"
className="px-4 mx-4"
onClick={() => {
netlifyIdentity.logout();
}}
>
Log out {user.user_metadata.full_name}
</Button>
)}
<div className="container my-5">
<Form
onSubmit={async (e) => {
e.preventDefault();
await addTodo({ variables: { text: inputRef.current.value } });
inputRef.current.value = '';
await refetch();
}}
>
<Form.Group className="d-flex justify-content-between">
<Form.Label htmlFor="add-die-todo">Add een todo </Form.Label>
<Form.Control type="text" placeholder="Enter text" ref={inputRef} />
<Button type="submit" className="mb-2">
Submit
</Button>
</Form.Group>
<div className="container mt-5 ">
{loading ? <div>loading...</div> : null}
{error ? <div>{error.message}</div> : null}
{!loading && !error && (
<ListGroup as="ul">
{data.todos.map((todo) => (
<ListGroup.Item
eventKey={todo.id}
key={todo.id}
as="li"
className="d-flex justify-content-evenly"
onClick={async () => {
await updateTodoDone({ variables: { id: todo.id } });
await refetch();
}}
>
<InputGroup.Checkbox
aria-label="Checkbox for following text input"
checked={todo.done}
/>
<span>{todo.text}</span>
</ListGroup.Item>
))}
{console.log('DATA van dashboard #mnfx:', data)}
</ListGroup>
)}
</div>
</Form>
</div>
</div>
);
};
export default Dashboard;
I think this must do it… Help is greatly wanted. Thanks in advance!