2016-06-17 7 views
0

Relay Todoの例から変更されたコードで変異を設定しようとしています。GraphQL Validation Error on mutation

は、私は次のエラーを取得するコンパイルしようとすると:私は藤堂コードを重複している

-- GraphQL Validation Error -- AddCampaignMutation -- 

File: /Users/me/docker/relay/examples/todo/js/mutations/AddCampaignMutation.js 
Error: Cannot query field "addCampaign" on type "Mutation". 
Source: 
> 
> mutation AddCampaignMutation {addCampaign} 
>        ^^^ 

-- GraphQL Validation Error -- AddCampaignMutation -- 

File: /Users/me/docker/relay/examples/todo/js/mutations/AddCampaignMutation.js 
Error: Unknown type "AddCampaignPayload". Did you mean "AddTodoPayload" or "RenameTodoPayload"? 
Source: 
> 
> fragment AddCampaignMutationRelayQL on AddCampaignPayload @relay(pattern: true) { 
>          ^^ 

ので、藤堂変異が正しく動作している理由を私は知らないが、私の新しいキャンペーンのテストではありません。

これは私が読みやすい文書を作成する藤堂関連の項目を削除して、私のdatabase.jsファイルです:

export class Campaign {} 
export class User {} 

// Mock authenticated ID 
const VIEWER_ID = 'me'; 

// Mock user data 
const viewer = new User(); 
viewer.id = VIEWER_ID; 
const usersById = { 
    [VIEWER_ID]: viewer, 
}; 

// Mock campaign data 
const campaignsById = {}; 
const campaignIdsByUser = { 
    [VIEWER_ID]: [], 
}; 

let nextCampaignId = 0; 
addCampaign('Campaign1'); 
addCampaign('Campaign2'); 
addCampaign('Campaign3'); 
addCampaign('Campaign4'); 

export function addCampaign(text) { 
    const campaign = new Campaign(); 
    //campaign.complete = !!complete; 
    campaign.id = `${nextCampaignId++}`; 
    campaign.text = text; 
    campaignsById[campaign.id] = campaign; 
    campaignIdsByUser[VIEWER_ID].push(campaign.id); 
    return campaign.id; 
} 

export function getCampaign(id) { 
    return campaignsById[id]; 
} 

export function getCampaigns(status = 'any') { 
    const campaigns = campaignIdsByUser[VIEWER_ID].map(id => campaignsById[id]); 
    if (status === 'any') { 
    return campaigns; 
    } 
    return campaigns.filter(campaign => campaign.complete === (status === 'completed')); 
} 

これは私のschema.jsファイルで、再び私は藤堂関連の項目を削除しました文書が読みやすくするために:

import { 
    GraphQLBoolean, 
    GraphQLID, 
    GraphQLInt, 
    GraphQLList, 
    GraphQLNonNull, 
    GraphQLObjectType, 
    GraphQLSchema, 
    GraphQLString, 
} from 'graphql'; 

import { 
    connectionArgs, 
    connectionDefinitions, 
    connectionFromArray, 
    cursorForObjectInConnection, 
    fromGlobalId, 
    globalIdField, 
    mutationWithClientMutationId, 
    nodeDefinitions, 
    toGlobalId, 
} from 'graphql-relay'; 

import { 

    Campaign, 
    addCampaign, 
    getCampaign, 
    getCampaigns, 

    User, 
    getViewer, 
} from './database'; 

const {nodeInterface, nodeField} = nodeDefinitions(
    (globalId) => { 
    const {type, id} = fromGlobalId(globalId); 
    if (type === 'User') { 
     return getUser(id); 
    } else if (type === 'Campaign') { 
     return getCampaign(id); 
    } 
    return null; 
    }, 
    (obj) => { 
    if (obj instanceof User) { 
     return GraphQLUser; 
    } else if (obj instanceof Campaign) { 
     return GraphQLCampaign; 
    } 
    return null; 
    } 
); 

/** 
* Define your own connection types here 
*/ 


const GraphQLAddCampaignMutation = mutationWithClientMutationId({ 
    name: 'AddCampaign', 
    inputFields: { 
    text: { type: new GraphQLNonNull(GraphQLString) }, 
    }, 
    outputFields: { 
    campaignEdge: { 
     type: GraphQLCampaignEdge, 
     resolve: ({localCampaignId}) => { 
     const campaign = getCampaign(localCampaignId); 
     return { 
      cursor: cursorForObjectInConnection(getCampaigns(), campaign), 
      node: campaign, 
     }; 
     }, 
    }, 
    viewer: { 
     type: GraphQLUser, 
     resolve:() => getViewer(), 
    }, 
    }, 
    mutateAndGetPayload: ({text}) => { 
    const localCampaignId = addCampaign(text); 
    return {localCampaignId}; 
    }, 
}); 

const GraphQLCampaign = new GraphQLObjectType({ 
    name: 'Campaign', 
    description: 'Campaign integrated in our starter kit', 
    fields:() => ({ 
    id: globalIdField('Campaign'), 
    text: { 
     type: GraphQLString, 
     description: 'Name of the campaign', 
     resolve: (obj) => obj.text, 
    } 
    }), 
    interfaces: [nodeInterface] 
}); 

const { 
    connectionType: CampaignsConnection, 
    edgeType: GraphQLCampaignEdge, 
} = connectionDefinitions({ 
    name: 'Campaign', 
    nodeType: GraphQLCampaign, 
}); 

const GraphQLUser = new GraphQLObjectType({ 
    name: 'User', 
    fields: { 
    id: globalIdField('User'), 
    campaigns: { 
     type: CampaignsConnection, 
     args: { 
     ...connectionArgs, 
     }, 
     resolve: (obj, {...args}) => 
     connectionFromArray(getCampaigns(), args), 
    },  
    totalCount: { 
     type: GraphQLInt, 
     resolve:() => getTodos().length, 
    }, 
    completedCount: { 
     type: GraphQLInt, 
     resolve:() => getTodos('completed').length, 
    }, 
    }, 
    interfaces: [nodeInterface], 
}); 

const Root = new GraphQLObjectType({ 
    name: 'Root', 
    fields: { 
    viewer: { 
     type: GraphQLUser, 
     resolve:() => getViewer(), 
    }, 
    node: nodeField, 
    }, 
}); 

はこれが私のAddCampaignMutation.jsファイルです:

import Relay from 'react-relay'; 

export default class AddCampaignMutation extends Relay.Mutation { 
    static fragments = { 
    viewer:() => Relay.QL` 
     fragment on User { 
     id, 
     totalCount, 
     } 
    `, 
    }; 
    getMutation() { 
    console.log('getMutation'); 
    return Relay.QL`mutation{addCampaign}`; 
    } 
    getFatQuery() { 
    console.log('getFatQuery'); 
    return Relay.QL` 
     fragment on AddCampaignPayload @relay(pattern: true) { 
     campaignEdge, 
     viewer { 
      campaigns, 
     }, 
     } 
    `; 
    } 
    getConfigs() { 
    console.log('getConfigs'); 
    return [{ 
     type: 'RANGE_ADD', 
     parentName: 'viewer', 
     parentID: this.props.viewer.id, 
     connectionName: 'campaigns', 
     edgeName: 'campaignEdge', 
     rangeBehaviors: ({orderby}) => { 
     if (orderby === 'newest') { 
      return 'prepend'; 
     } else { 
      return 'append'; 
     } 
     },  
     //rangeBehaviors: ({status}) => { 
     // if (status === 'completed') { 
     // return 'ignore'; 
     // } else { 
     // return 'append'; 
     // } 
     //}, 
    }]; 
    } 
    getVariables() { 
    console.log('getVariables'); 
    return { 
     text: this.props.text, 
    }; 
    } 
    getOptimisticResponse() { 
    console.log('getOptimisticResponse'); 
    return { 
     // FIXME: totalCount gets updated optimistically, but this edge does not 
     // get added until the server responds 
     campaignEdge: { 
     node: { 
      text: this.props.text, 
     }, 
     }, 
     viewer: { 
     id: this.props.viewer.id, 
     totalCount: this.props.viewer.totalCount + 1, 
     }, 
    }; 
    } 
} 

そして最後に、これは私のテキスト入力とAddCampaignMutationへの呼び出しが含まれているアプリファイルです:

import AddTodoMutation from '../mutations/AddTodoMutation'; 
import AddCampaignMutation from '../mutations/AddCampaignMutation'; 
import TodoListFooter from './TodoListFooter'; 
import TodoTextInput from './TodoTextInput'; 

import React from 'react'; 
import Relay from 'react-relay'; 

class TodoApp extends React.Component { 
    _handleTextInputSave = (text) => { 
    debugger; 
    this.props.relay.commitUpdate(
     new AddTodoMutation({text, viewer: this.props.viewer}) 
    ); 
    }; 

    _campaignHandleTextInputSave = (text) => { 
    debugger; 
    this.props.relay.commitUpdate(
     new AddCampaignMutation({text, viewer: this.props.viewer}) 
    ); 
    }; 

    render() { 
    const hasTodos = this.props.viewer.totalCount > 0; 
    return (
     <div> 
     <section className="todoapp"> 
      <header className="header"> 
      <TodoTextInput 
       autoFocus={true} 
       className="new-campaign" 
       onSave={this._campaignHandleTextInputSave} 
       placeholder="Campaign name" 
      />   
      <h1> 
       todos 
      </h1> 
      <TodoTextInput 
       autoFocus={true} 
       className="new-todo" 
       onSave={this._handleTextInputSave} 
       placeholder="What needs to be done?" 
      /> 
      </header> 

      {this.props.children} 

      {hasTodos && 
      <TodoListFooter 
       todos={this.props.viewer.todos} 
       viewer={this.props.viewer} 
      /> 
      } 
     </section> 
     </div> 
    ); 
    } 
} 

export default Relay.createContainer(TodoApp, { 
    fragments: { 
    viewer:() => Relay.QL` 
     fragment on User { 
     totalCount, 
     ${AddTodoMutation.getFragment('viewer')}, 
     ${AddCampaignMutation.getFragment('viewer')}, 
     ${TodoListFooter.getFragment('viewer')}, 
     } 
    `, 
    }, 
}); 

答えて

0

まあ、私は少し愚かな感じが、私は、問題が何であったかが分かりました。私のschema.jsonファイルが更新されていないことに気付かなかった!

誰でも同様の問題がschema.jsonファイルがそれを再構築するには、次のコマンドを実行して、最新の状態であることを確認している場合は:

NPMの実行スクリプトの更新スキーマ

関連する問題