The Vuex store of my Vue.js application is growing and getting a little bit messy with a lot of constants in it. I would like to split these constants in separate files and import them into my Vuex store store.js. I'm new to JavaScript so I would like to know:
How to store these constants in separate files? What would be the syntax in these files?
How to import these constants in store.js? What would be the exact syntax to do so?
Here is the current content of my store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export const store = new Vuex.Store({
state: {
graphqlUrl: 'https://localhost/listof/api/v1/graphql',
errorObject: {
flag: false,
message: ''
},
// Data types queries
queryGetAllDataTypes: `query getAllDataTypes {
allSysDataTypes(orderBy: NAME_ASC) {
nodes {
id
name
}
}
}`,
// Data for linked list & attributes drodpdown in attribute form
// Response labels must be formatted according to Treeselect requirements
queryGetLinkedLists: `query getAllLists {
allSysLists(orderBy: NAME_ASC) {
nodes {
id:nodeId
label:name
attributes:sysAttributesByListId {
children:nodes {
id
label:name
}
}
}
}
}`,
// Data for linked list & attributes drodpdown in value form
// Response labels must be formatted according to Treeselect requirements
queryGetLinkedListValues: `query getAllValues {
all<GraphQlListName> {
nodes {
id
label:<graphQlAttributeName>
}
}
}`,
// Lists queries and mutations
queryGetAllLists: `query getAllLists{
allSysLists(orderBy: NAME_ASC) {
nodes {
id
name
description
}
}
}`,
queryGetList: `query getList($id: Int!) {
sysListById(id: $id) {
id
name
description
tableName
sysAttributesByListId {
nodes {
id
name
description
flagMandatory
flagUnique
dataTypeId
sysDataTypeByDataTypeId { name }
linkedAttributeId
sysAttributeByLinkedAttributeId {
name
columnName
listId
sysListByListId {
name
tableName
}
}
columnName
}
}
}
}`,
mutationCreateList: `mutation createList($sysList: SysListInput!) {
createSysList(input: {sysList: $sysList}) {
sysList {
id
}
}
}`,
mutationUpdateList: `mutation updateList($id: Int!, $sysListPatch: SysListPatch!) {
updateSysListById(input: {id: $id, sysListPatch: $sysListPatch }) {
sysList {
id
}
}
}`,
mutationDeleteList: `mutation deleteList($id: Int!) {
deleteSysListById(input: {id: $id}){
sysList {
id
}
}
}`,
// Attributes queries and mutations
queryGetAttribute: `query getAttribute($id: Int!) {
sysAttributeById(id: $id) {
id
name
description
flagMandatory
flagUnique
dataTypeId
sysDataTypeByDataTypeId { name }
linkedAttributeId
sysAttributeByLinkedAttributeId {
name
listId
sysListByListId { name }
}
defaultValue
}
}`,
mutationCreateAttribute: `mutation createAttribute($sysAttribute: SysAttributeInput!) {
createSysAttribute(input: {sysAttribute: $sysAttribute}) {
sysAttribute {
id
}
}
}`,
mutationUpdateAttribute: `mutation updateAttribute($id: Int!, $sysAttributePatch: SysAttributePatch!) {
updateSysAttributeById(input: {id: $id, sysAttributePatch: $sysAttributePatch }) {
sysAttribute {
id
}
}
}`,
mutationDeleteAttribute: `mutation deleteAttribute($id: Int!) {
deleteSysAttributeById(input: {id: $id}){
sysAttribute {
id
}
}
}`,
// Generic query used as template to fetch all values from a list
queryGetAllValues: `query getAllValues {
all<GraphQlListName> {
nodes {
id
createdDate
updatedDate
<graphQlAttributeName>
}
}
}`,
// Generic query used as template to fetch one value from a list
queryGetValue: `query getValue($id: Int!) {
<graphQlListName>ById(id: $id) {
id
createdDate
updatedDate
<graphQlAttributeName>
}
}`,
// Generic mutation used as template to create a new value in a list
mutationCreateValue: `mutation createValue($<graphQlListName>: <GraphQlListName>Input!) {
create<GraphQlListName>(input: {<graphQlListName>: $<graphQlListName>}) {
<graphQlListName> {
id
}
}
}`,
// Generic mutation used as template to update a value in a list
mutationUpdateValue: `mutation updateValue($id: Int!, $<graphQlListName>Patch: <GraphQlListName>Patch!) {
update<GraphQlListName>ById(input: {id: $id, <graphQlListName>Patch: $<graphQlListName>Patch }) {
<graphQlListName> {
id
}
}
}`,
// Generic mutation used as template to delete a value in a list
mutationDeleteValue: `mutation deleteValue($id: Int!) {
delete<GraphQlListName>ById(input: {id: $id}){
<graphQlListName> {
id
}
}
}`,
}
});
The simplest option is to create a new file for constants (constants.js) and define and export them there, e.g.:
export const cat = 'black'
export const dog = 'brown'
export const mouse = 'grey'
Then either import them all into the current namespace in store.js:
import * as constants from './constants'
Or import them selectively when needed:
import { cat, dog } from './constants'
VueX stores are immutable by default and can only be mutated via mutations. Vuex has created modules for this. I simply create a module and put all my constants in there without mutations.
From the vux documentation:
https://vuex.vuejs.org/guide/modules.html below:
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> `moduleA`'s state
store.state.b // -> `moduleB`'s state
Using nuxt.js you can simply add constants.js to the store folder with:
export const state = () => ({
example: {}
});
Related
I'm trying to catch info from GraphQL Gatsby with useStaticQuery but the data returned is undefined and I don't understand why because in my http://localhost:8000/___graphql I received the good information.
My code is not a page component it's a reason why I used Static Query
My code is like that:
import React from "react";
import { useStaticQuery, graphql} from "gatsby";
export default function MenuMD () {
const { data } = useStaticQuery(
graphql`
query {
allFile(filter: {sourceInstanceName: {eq: "markdown"}}) {
edges {
node {
childrenMarkdownRemark {
frontmatter {
slug
title
}
}
}
}
}
}
`
)
console.log('static data', data);
return<>Menu from MarkDown</>
}
the expected result from http://localhost:8000/___graphql is something like that:
{
"data": {
"allFile": {
"edges": [
{
"node": {
"childMarkdownRemark": {
"frontmatter": {
"slug": "/projet_m",
"title": "Projet M"
}
}
}
},
{
"node": {
"childMarkdownRemark": {
"frontmatter": {
"slug": "/projet_n",
"title": "Projet N"
}
}
}
}
]
}
},
"extensions": {}
}
May be there is a reason for this undefined return?
Assuming that the query is working in the GraphiQL environment and there's a "markdown" sourceInstanceName in your data structure, try it like this:
export default function MenuMD() {
const data = useStaticQuery(
graphql`
query {
allFile(filter: { sourceInstanceName: { eq: "markdown" } }) {
edges {
node {
childrenMarkdownRemark {
frontmatter {
slug
title
}
}
}
}
}
}
`
);
console.log("static data", data);
return <>Menu from MarkDown</>;
}
There's nothing wrong using a static query in a component rather than a page, the result must be exactly the same (in terms of output).
Your data should be inside data.allFile.edges (or d'estructures directly as { allFile }) not directly destructuring the result of the static query as data. That's why data was undefined in your case.
with graphQL we can fetch data with "where"
query{
activities(where: {date: "2020-08-01"}){
date
collect
}
}
How change the date value to params ?
I try this :
let date = "2020-01-08"
const { loading, error, data } = useQuery(GET_ACTIVITY, {
variables: {
input: {
where: { date: date }
}
}
});
First the schema definition from your back-end must be something like this:
type Activity {
date: String
collect: String
...
}
type Query {
activities(date: String): [Activity]
...
}
then in the front-end create the query using the gql function from #apollo/client:
import { gql, useQuery } from '#apollo/client';
...
const GET_ACTIVITY = gql`
query Activities($date: String!) {
activities(date: $date){
date
collect
}
}
`;
And finally call it like this:
let date = "2020-01-08";
const { loading, error, data } = useQuery(GET_ACTIVITY, {
variables: {
date
}
});
More about queries: https://www.apollographql.com/docs/react/data/queries
I have this fragment:
// product-info.js
module.exports = gql`fragment productInfo on Product {
id
name
model
color
quantity
}`
And I have this query:
// get-products.js
const productInfo = require('./fragments/product-info')
module.exports = gql`query getProducts {
quote #client {
items { ...productInfo }
}
}`
This is not working because ...productInfo is a simple literal here.
Even string interpolation is not working ${...productInfo}.
You should include the string after the query, I don't know if it will work with gql tag, depends on your bundler settings:
module.exports = gql`query getProducts {
quote #client {
items { ...productInfo }
}
}
fragment productInfo on Product {
id
name
model
color
quantity
}`
Other options is include with string formatter:
const productInfo = require('./fragments/product-info')
module.exports = gql`query getProducts {
quote #client {
items { ...productInfo }
}
}
${productInfo}`
I'm constructing a GraphQL query using vue-apollo and graphql-tag.
If I hardcode the ID I want, it works, but I'd like to pass the current route ID to Vue Apollo as a variable.
Does work (hardcoded ID):
apollo: {
Property: {
query: PropertyQuery,
loadingKey: 'loading',
variables: {
id: 'my-long-id-example'
}
}
}
However, I'm unable to do this:
Doesn't work (trying to access this.$route for the ID):
apollo: {
Property: {
query: PropertyQuery,
loadingKey: 'loading',
variables: {
id: this.$route.params.id
}
}
}
I get the error:
Uncaught TypeError: Cannot read property 'params' of undefined
Is there any way to do this?
EDIT: Full script block to make it easier to see what's going on:
<script>
import gql from 'graphql-tag'
const PropertyQuery = gql`
query Property($id: ID!) {
Property(id: $id) {
id
slug
title
description
price
area
available
image
createdAt
user {
id
firstName
lastName
}
}
}
`
export default {
name: 'Property',
data () {
return {
title: 'Property',
property: {}
}
},
apollo: {
Property: {
query: PropertyQuery,
loadingKey: 'loading',
variables: {
id: this.$route.params.id // Error here!
}
}
}
}
</script>
You can't have access to "this" object like that:
variables: {
id: this.$route.params.id // Error here!
}
But you can like this:
variables () {
return {
id: this.$route.params.id // Works here!
}
}
Readimg the documentation( see Reactive parameters section) of vue-apollo you can use vue reactive properties by using this.propertyName. So just initialize the route params to a data property as then use it in you apollo object like this
export default {
name: 'Property',
data () {
return {
title: 'Property',
property: {},
routeParam: this.$route.params.id
}
},
apollo: {
Property: {
query: PropertyQuery,
loadingKey: 'loading',
// Reactive parameters
variables() {
return{
id: this.routeParam
}
}
}
}
}
While the accepted answer is correct for the poster's example, it's more complex than necessary if you're using simple queries.
In this case, this is not the component instance, so you can't access this.$route
apollo: {
Property: gql`{object(id: ${this.$route.params.id}){prop1, prop2}}`
}
However, you can simply replace it with a function, and it will work as you might expect.
apollo: {
Property () {
return gql`{object(id: ${this.$route.params.id}){prop1, prop2}}`
}
}
No need for setting extra props.
I'm trying to wrap my Chat component with two queries and one mutation using compose.
However, I'm still getting the following error in the console:
Uncaught Error: react-apollo only supports a query, subscription, or a mutation per HOC. [object Object] had 2 queries, 0 subscriptions and 0 mutations. You can use 'compose' to join multiple operation types to a component
Here are my queries and the export statement:
// this query seems to cause the issue
const findConversations = gql`
query allConversations($customerId: ID!) {
allConversations(filter: {
customerId: $customerId
})
} {
id
}
`
const createMessage = gql`
mutation createMessage($text: String!, $conversationId: ID!) {
createMessage(text: $text, conversationId: $conversationId) {
id
text
}
}
`
const allMessages = gql`
query allMessages($conversationId: ID!) {
allMessages(filter: {
conversation: {
id: $conversationId
}
})
{
text
createdAt
}
}
`
export default compose(
graphql(findConversations, {name: 'findConversationsQuery'}),
graphql(allMessages, {name: 'allMessagesQuery'}),
graphql(createMessage, {name : 'createMessageMutation'})
)(Chat)
Apparently, the issue is with the findConversations query. If I comment it out, I don't get the error and the component loads properly:
// this works
export default compose(
// graphql(findConversations, {name: 'findConversationsQuery'}),
graphql(allMessages, {name: 'allMessagesQuery'}),
graphql(createMessage, {name : 'createMessageMutation'})
)(Chat)
Can anyone tell me what I'm missing?
By the way, I also have a subscription set up on the allMessagesQuery, in case that's relevant:
componentDidMount() {
this.newMessageSubscription = this.props.allMessagesQuery.subscribeToMore({
document: gql`
subscription {
createMessage(filter: {
conversation: {
id: "${this.props.conversationId}"
}
}) {
text
createdAt
}
}
`,
updateQuery: (previousState, {subscriptionData}) => {
...
},
onError: (err) => console.error(err),
})
}
Your findConversationsQuery is actually two queries. This one:
query allConversations($customerId: ID!) {
allConversations(filter: {
customerId: $customerId
})
}
And this one:
{
id
}
The entire query needs to be enclosed between a single pair of opening and closing brackets.
I think what you meant to write is:
query allConversations($customerId: ID!) {
allConversations(filter: { customerId: $customerId }){
id
}
}