Hello Guys,
I created a Meteor Apollo App, in which data is stored in both mongodb and sql db. I successfully delete data from mongodb. Now I want to delete sql data from sql database, but I am stuck here. I go through so many tutorials and blogs but there is no success.
Any idea or suggestion about this problem.
Thanks.
What have you tried? It should be very similar to MongoDB, just use a JavaScript SQL library.
Hello @sashko,
Thanks for reply. I want to share code snippets step by step which I have tried. Sorry for bulk amount of code, but I urgently need solution.
connectors.js ->
import Sequelize from 'sequelize';
// create the connection for Sql
const sqlDb = new Sequelize('apollodemo', "root", "password", {
host: 'localhost',
dialect: 'mysql'
});
// define the model
const PostModel = sqlDb.define('post', {
content: { type: Sequelize.STRING },
views: { type: Sequelize.INTEGER }
},{
timestamps: false
});
// create the table if it doesn't exist yet
sqlDb.sync();
// export Post
const Post = sqlDb.models.post;
export { Post };
resolvers.js ->
import { Post } from './connectors';
import MongoPosts from './collections';
// create the resolve functions for the available GraphQL queries
export default resolvers = {
Query: {
posts(_, args){
// console.log("Post >>>> ", Post.findAll({where: args}));
return Post.findAll({where: args});
},
mongoPost(_, args) {
// console.log("mongoPost Query ARGS >>>> ", args);
// console.log("mongoPost >>>> ", MongoPosts.find().fetch());
return MongoPosts.find().fetch();
},
},
Mutation: {
addPost(_, args) {
return Post.create(args);
},
deletePost(_, args) {
console.log("deletePost ARGS >>>> ", args, args.id);
return Post.delete({where: args});
},
addMongoPost(_, args) {
// console.log("> ARGS = > ",args);
return MongoPosts.insert(args);
},
deleteMongoPost(_, args) {
// console.log("deleteMongoPost ARGS >>>> ", args);
return MongoPosts.remove({_id: args._id});
}
}
};
schema.js ->
export default typeDefs = [`
type Post {
id: Int
content: String
views: Int
}
type DeletePost{
id: Int
}
type MongoPost {
_id: String
content: String
views: Int
}
type MongoPostsDelete{
_id: String
}
type Query {
posts(views: Int): [Post]
mongoPost(views: Int): [MongoPost]
}
# this schema allows the following mutation:
type Mutation {
addPost (
content: String!,
views: Int
): Post
deletePost (
id: Int
): [DeletePost]
addMongoPost (
content: String!,
views: Int
): Post
deleteMongoPost (
_id: String
): [MongoPostsDelete]
}
schema {
query: Query
mutation: Mutation
}
`];
App.js ->
/**
* The top level react component
*/
import React, { Component } from 'react';
import PostsContainer from './postsContainer'
import MessageFormContainer from './messageFormContainer'
export default class App extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="row">
<div className="col-sm-4">
<h4>MySQL Data</h4>
<PostsContainer source="mysql" />
</div>
<div className="col-sm-4">
<h4>Select Database</h4>
<MessageFormContainer />
</div>
<div className="col-sm-4">
<h4>MongoDB Data</h4>
<PostsContainer source="mongodb" />
</div>
</div>
)
}
}
messageForm.js ->
import React, { Component, PropTypes } from 'react';
export class MessageForm extends Component {
constructor(props) {
super(props);
// bind event handlers to this
this.submitMessage = this.submitMessage.bind(this);
this.handleMessageChange = this.handleMessageChange.bind(this);
// initialize component refs
this.messageInput = null;
// initialize the state
this.state = {
message: null
};
}
render() {
return (
<div className="row">
<form className="col-sm-12" onSubmit={this.submitMessage}>
<div className="form-group">
<input name="database" type="radio" id="mysql" value="mysql" />
<label htmlFor="mysql"> MySQL</label>
</div>
<div className="form-group">
<input name="database" type="radio" id="mongodb" value="mongodb" />
<label htmlFor="mongodb"> MongoDB</label>
</div>
<div className="input-group">
<input ref={(c) => this.messageInput = c} className="form-control" placeholder="Enter Your Post here." id="message" type="text" onChange={this.handleMessageChange} required />
<span className="input-group-btn">
<button type="submit" className="btn btn-default" title="Please click here.">
<span className="glyphicon glyphicon-play"></span>
</button>
</span>
</div>
</form>
</div>
)
}
handleMessageChange(event) {
this.setState({message: event.target.value})
}
submitMessage(event) {
event.preventDefault()
let databaseName = $("[name='database']:checked").val()
if(databaseName == "mysql"){
this.props.MySQLsubmit(this.state.message);
this.messageInput.value = "";
}else if(databaseName == "mongodb"){
this.props.MongoDBsubmit(this.state.message);
this.messageInput.value = "";
}else{
alert("Please select any one data source");
}
}
}
MessageForm.propTypes = {
MySQLsubmit: PropTypes.func.isRequired,
MongoDBsubmit: PropTypes.func.isRequired
};
messageFormContainer.js ->
import React, { Component } from 'react';
import gql from 'graphql-tag';
import { graphql } from 'react-apollo';
import { MessageForm } from './messageForm';
const addMySQlPost = gql`
mutation addMySQLPostMutation ($content: String!) {
addPost(content: $content) {
id,
content
}
}
`;
const addMongoDBPost = gql`
mutation addMongoDBPostMutation ($content: String!) {
addMongoPost(content: $content) {
id,
content
}
}
`;
export default MessageFormContainer = graphql(addMySQlPost, {
props: ({ mutate }) => ({
MySQLsubmit: (content) => mutate({
variables: { content }
}),
})
})(
graphql(addMongoDBPost, {
props: ({ mutate }) => ({
MongoDBsubmit: (content) => mutate({
variables: { content }
}),
})
})
(MessageForm));
post.js ->
import React, { Component, PropTypes } from 'react';
export default class Post extends Component {
constructor(props) {
super(props);
this.removeMessage = this.removeMessage.bind(this);
}
render() {
// console.log("Post props >>>>>>", this.props)
return (
<tr>
<td>{this.props.source == 'mysql' ? this.props.post.id : this.props.post._id}</td>
<td>{this.props.post.content}</td>
<td>
<button type="button" onClick={this.removeMessage} id="delete"><span className="glyphicon glyphicon-remove-sign"></span></button>
</td>
</tr>
)
}
removeMessage(event) {
event.preventDefault();
console.log("Remove function called")
// console.log("Data source >>>>", this.props.source, "id >>>", this.props.post.id ? this.props.post.id : '', this.props.post._id ? this.props.post._id : '');
console.log("Post props >>>>>>", this.props)
if(this.props.source == 'mysql') {
console.log("source >>>>", this.props.source, "id >>", this.props.post.id)
this.props.deleteSqlPost(this.props.post.id)
}else{
console.log("source >>>>", this.props.source, "id >>", this.props.post._id)
this.props.deleteMongoDbPost(this.props.post._id)
}
}
}
// Post requires props with a post attribute with a content attribute of type string
Post.propTypes = {
post: PropTypes.shape({
content: PropTypes.string
}).isRequired,
deleteMongoDbPost: PropTypes.func.isRequired,
deleteSqlPost: PropTypes.func.isRequired
};
postsContainer.js ->
import React, { Component, PropTypes } from 'react';
import { graphql } from 'react-apollo';
import gql from 'graphql-tag';
import Post from './post';
/**
* This React component is responsible for querying Apollo for the posts
* and passing the results to the child Post components for rendering
*/
class Posts extends Component {
constructor(props) {
super(props);
}
render() {
// console.log("Posts >>>>>", this.props.data)
let posts = <div></div>
// let ourProps = this.props;
let receivedData = this.props.source == "mysql" ? this.props.data.posts : this.props.data.mongoPost;
if (receivedData && receivedData instanceof Array) {
posts = (
<table className="table">
<thead>
<tr>
<th>Id</th>
<th>Post</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
{
receivedData.map((post, index)=> {
return (
<Post key={index} post={post} source={this.props.source} {...this.props} />
)
})
}
</tbody>
</table>
)
}
return posts;
}
}
// Posts requires props with a data attribute of an array of posts
Posts.propTypes = {
data: PropTypes.shape({
posts: PropTypes.array,
mongoPost: PropTypes.array
}).isRequired
};
// Define the graphql query to retrieve the posts and the desired attributes
const allPosts = gql`
query PostsForDisplay {
posts {
id,
content,
views
}
mongoPost {
_id,
content,
views
}
}
`;
const deleteMySQlPost = gql`
mutation deleteMySQLPostMutation ($id: Int!) {
deletePost(id: $id) {
id
}
}
`;
const deleteMongodbPost = gql`
mutation deleteMongoPostMutation ($id: String) {
deleteMongoPost(_id: $id) {
_id
}
}
`;
// Define the graphql mutation for deleting the posts
/*const EditPostMutation = gql`
mutation editPost($content: String) {
edit(content: $content)
}
`;*/
export default MessageFormContainer = graphql(allPosts, {
options: { pollInterval: 5000 }
})(graphql(deleteMongodbPost, {
props: ({ mutate }) => ({
deleteMongoDbPost: (id) => mutate({
variables: { id }
}),
})
})(graphql(deleteMySQlPost, {
props: ({ mutate }) => ({
deleteSqlPost: (id) => ({
variables: { id }
}),
})
})(Posts)
));
// Use the graphql container to run the allPosts query and pass the results to PostsContainer
/*export default PostsContainer = graphql(allPosts, {
options: { pollInterval: 5000 }
})(Posts);*/
Is this being called and printing anything? Have you looked in the Chrome network tab to see if a GraphQL request is being sent to the server for the mutation?
@sashko
It will print nothing on the console (I think, sql delete mutation is not called) and after checking chrome network tab, it seems that request is not sent to server for the mutation in case of sql delete, but in case of mongo delete, request is sent to server for mutation.
Please check this - https://github.com/DeligenceTechnologies/Meteor-Apollo-with-MongoDB-MySQL - We have deleted the records from MySQL database [beside doing other stuff] - It might be helpful for you.
Hello @sashko,
Sorry for late response. Here is the github link of my code.
https://github.com/divyanshupathak/MeteorApolloDemo
Please check and advice.