Nuxt dynamic route population using graphQL - graphql

In nuxtconfig.js you can use
generate: { routes() {} }
to return all the dynamic routes for your app.
All the examples use axios ie:
import axios from 'axios'
export default {
generate: {
routes: function () {
return axios.get('https://my-api/users')
.then((res) => {
return res.data.map((user) => {
return {
route: '/users/' + user.id,
payload: user
}
})
})
}
}
}
How can i do this with graphQL / apollo?
I have tried this and some other combinations...
let v
apollo: {
posts: {
query: gql`
query posts {
posts {
title
}
}
`,
result({ data, loading, networkStatus }) {
v = data
}
}
},
generate: {
subFolders: true,
routes: function() {
return {
route: '/posts/' + v.title,
payload: v
}
}
},
The error is that i dont think apollo is able to be used in nuxtconfig?
This also doesnt work
generate: {
routes: function() {
apollo: {
posts: {
query:`query posts {
posts {
title
}
}
`,
result({ data, loading, networkStatus }) {
return {
route: '/posts/' + data.title,
payload: data
}
}
}
},
}
},

Related

why does my graphql return an empty array?

I am newbie with graphql. I have a front-end project (nextjs) and back-end(strapi).
This is my code
import { ApolloClient, InMemoryCache, gql } from '#apollo/client'
export default function Blog({ posts }) {
console.log('posts', posts)
return (
<div>
{posts.map(post => {
return (
<div>
<p>{posts.heading}</p>
</div>
)
})}
</div>
)
}
export async function getStaticProps() {
const client = new ApolloClient({
url: 'http://localhost:1337/graphql/',
cache: new InMemoryCache(),
})
const { data } = await client.query({
query: gql`
query {
posts {
data {
attributes {
heading
}
}
}
}
`,
})
return {
props: {
posts: data.posts,
},
}
}
alongside this, I also get this message "cannot destructure property of intermediate value". Does anybody know why, i'm sure the code is correct.
Firstly i recommend creating a folder in root and put all graphql codes and you have also a syntax error:
let me give you an example:
/index.js
import { ApolloClient, InMemoryCache, gql } from "#apollo/client";
const client = new ApolloClient({
uri: API,
cache: new InMemoryCache(),
defaultOptions: {
query: {
fetchPolicy: "network-only",
},
},
});
//get category ids
const getCatIds = async () => {
try {
const { data } = await client.query({
query: gql`
query categoriesId {
categories(sort: "id:ASC") {
id
name
}
}
`,
});
return data.categories;
} catch {
console.log("error appolo");
}
};
export {getCatIds}

"Invalid URL: words" - apollo-server

I would like to create small project using GraphqQL, ApolloServer, but I encountered a problem, that I can't solve. I wrote it based on several documentation.
const { ApolloServer, gql } = require('apollo-server');
const { RESTDataSource } = require('apollo-datasource-rest');
const typeDefs = gql`
type Word {
id: ID!
word: String!
translation: String!
}
type Query {
words: [Word]
word(id: ID): Word
}
`;
class WordsAPI extends RESTDataSource {
constructor() {
super();
this.baseURL = 'localhost:5001/'
}
async getWord(id) {
return this.get(`word/${id}`)
}
async getAllWords() {
return this.get('words')
}
async getSpecifiedWords(SpecWord) {
return this.get(`words/${SpecWord}`)
}
}
const resolvers = {
Query: {
words: (_, __, { dataSources }) =>
dataSources.wordsAPI.getAllWords(),
word: async (_source, { id }, { dataSources }) => {
return dataSources.wordsAPI.getWord(id);
}
}
}
const server = new ApolloServer({
typeDefs,
resolvers,
dataSources: () => {
return {
wordsAPI: new WordsAPI()
};
},
context: () => {
return {
};
},
});
server.listen().then(({ url }) => {
console.log(`🚀 Server ready at ${url}`);
});
After
query {
words {
translation
}
}
In playground I am getting Invalid URL: words.
At localhost:5001/words is database and in Postman it works.
What did I bad?

GraphQL Subscriptions return an empty (null) response [duplicate]

I have the following GRAPHQL subscription:
Schema.graphql
type Subscription {
booking: SubscriptionData
}
type SubscriptionData {
booking: Booking!
action: String
}
And this is the resolver subsrciption file
Resolver/Subscription.js
const Subscription = {
booking: {
subscribe(parent, args, { pubsub }, info) {
return pubsub.asyncIterator("booking");
}
}
};
export default Subscription;
Then I have the following code on the Mutation in question
pubsub.publish("booking", { booking: { booking }, action: "test" });
I have the follow subscription file in front end (React)
const getAllBookings = gql`
query {
bookings {
time
durationMin
payed
selected
activity {
name
}
}
}
`;
const getAllBookingsInitial = {
query: gql`
query {
bookings {
time
durationMin
payed
selected
activity {
name
}
}
}
`
};
class AllBookings extends Component {
state = { allBookings: [] }
componentWillMount() {
console.log('componentWillMount inside AllBookings.js')
client.query(getAllBookingsInitial).then(res => this.setState({ allBookings: res.data.bookings })).catch(err => console.log("an error occurred: ", err));
}
componentDidMount() {
console.log(this.props.getAllBookingsQuery)
this.createBookingsSubscription = this.props.getAllBookingsQuery.subscribeToMore(
{
document: gql`
subscription {
booking {
booking {
time
durationMin
payed
selected
activity {
name
}
}
action
}
}
`,
updateQuery: async (prevState, { subscriptionData }) => {
console.log('subscriptionData', subscriptionData)
const newBooking = subscriptionData.data.booking.booking;
const newState = [...this.state.allBookings, newBooking]
this.setState((prevState) => ({ allBookings: [...prevState.allBookings, newBooking] }))
this.props.setAllBookings(newState);
}
},
err => console.error(err)
);
}
render() {
return null;
}
}
export default graphql(getAllBookings, { name: "getAllBookingsQuery" })(
AllBookings
);
And I get the following response:
data: {
booking: {booking: {...} action: null}}
I get that I am probably setting up the subscription wrong somehow but I don't see the issue.
Based on your schema, the desired data returned should look like this:
{
"booking": {
"booking": {
...
},
"action": "test"
}
}
The first booking is the field on Subscription, while the second booking is the field on SubscriptionData. The object you pass to publish should have this same shape (i.e. it should always include the root-level subscription field).
pubsub.publish('booking', {
booking: {
booking,
action: 'test',
},
})

Unable to fetch data from API (Resource blocked by client) in Vuex

I'm trying to fetch some data from my API using vuex + axios, but the action give me a "Network Error" (ERR_BLOCKED_BY_CLIENT).
when i was using json-server it works fine, but it doesn't work with my API even with 'Allow-Access-Control-Origin': '*'
actions
const actions = {
async fetchSearch({ commit, state }) {
let res
try {
res = await axios(`http://localhost:8000/api/advertisements/search?column=title&per_page=${state.params.per_page}&search_input=${state.params.query.toLowerCase()}&page=${state.params.page}`, {
method: 'GET',
mode: 'no-cors',
headers: {
'Content-Type': 'application/json'
}
})
} catch(err) {
console.log(err)
}
commit('clearProducts')
commit('setProducts', res.data)
},
setGlobalParams({ commit }, obj) {
commit('clearParams')
commit('setParams', obj)
}
}
component
<script>
/* Vuex import */
import { mapActions } from 'vuex'
export default {
name: 'base-search-component',
data() {
return {
query_obj: {
page: 1,
per_page: 8,
query: ''
}
}
},
methods: {
...mapActions([
'fetchSearch',
'setGlobalParams'
]),
fetchData() {
if (this.query_obj.query === '') {
return
} else {
this.setGlobalParams(this.query_obj)
this.fetchSearch()
this.$router.push({ name: 'search', params: { query_obj: this.query_obj } })
}
}
}
}
</script>
Assuming your cors issue was properly resolved the reason you cannot access the data is that it is being set before the axios promise is being resolved.
Change:
async fetchSearch({ commit, state }) {
let res
try {
res = await axios(`http://localhost:8000/api/advertisements/search?column=title&per_page=${state.params.per_page}&search_input=${state.params.query.toLowerCase()}&page=${state.params.page}`, {
method: 'GET',
mode: 'no-cors',
headers: {
'Content-Type': 'application/json'
}
})
} catch(err) {
console.log(err)
}
commit('clearProducts')
commit('setProducts', res.data)
}
to:
async fetchSearch({ commit, state }) {
await axios(`http://localhost:8000/api/advertisements/search?column=title&per_page=${state.params.per_page}&search_input=${state.params.query.toLowerCase()}&page=${state.params.page}`, {
method: 'GET',
mode: 'no-cors',
headers: {
'Content-Type': 'application/json'
}
}).then(function (response) {
commit('clearProducts')
commit('setProducts', response.data)
}).catch(err) {
console.log(err)
}
}
Further you should use mapState. Assuming setProducts is setting a state object like products this would look like:
<script>
/* Vuex import */
import { mapState, mapActions } from 'vuex'
export default {
name: 'base-search-component',
data() {
return {
query_obj: {
page: 1,
per_page: 8,
query: ''
}
}
},
computed: {
mapState([
'products'
])
},
methods: {
...mapActions([
'fetchSearch',
'setGlobalParams'
]),
fetchData() {
if (this.query_obj.query === '') {
return
} else {
this.setGlobalParams(this.query_obj)
this.fetchSearch()
this.$router.push({ name: 'search', params: { query_obj: this.query_obj } })
}
}
}
}
</script>
Now you can refrence this.products in JS or products in your template.

GraphQL query ( Apollo client link state ) returns empty object {}

The Query
const GET_MEMBER = gql`
query getMembers {
getMembers #client {
firstname
lastname
__typename
}
}
`
export { GET_MEMBER }
The Resolver:
export default {
resolvers: {
Query: {
getMembers: async (_, variables, { cache }) => {
try {
const res = await apiClient.get('/contacts')
return { ...res.data, __typename: 'Member' }
} catch (e) {
throw e
}
},
},
apiClient is an instance of axios
React App:
<Query query={GET_MEMBER}>
{({ loading, error, data }) => {....
I am getting this warning
and the Query in my React App returns {}
Where should I start to debeg it?

Resources