'compose not exported from react-apollo

I'm following a graphql tutorial on youtube (https://www.youtube.com/watch?v=ed8SzALpx1Q at about 3hr 16min) and part of it uses compose from "react-apollo". However, I'm getting an error because the new version of react-apollo does not export this.

I read online that I need to replace import { compose } from "react-apollo" with import { compose } from "recompose" but doing that produces the error TypeError: Cannot read property 'loading' of undefined I've also read that I should replace the import from react-apollo with import * as compose from "lodash" but when I do this I get other errors, saying that × TypeError: lodash__WEBPACK_IMPORTED_MODULE_2__(...) is not a function

App.js:

import React from "react";
import ApolloClient from "apollo-boost";
import { ApolloProvider } from "react-apollo";

import BookList from "./components/BookList";
import AddBook from "./components/AddBook";

//apollo client setup
const client = new ApolloClient({
  uri: "http://localhost:4000/graphql"
});

function App() {
  return (
    <ApolloProvider client={client}>
      <div className="main">
        <h1>My Reading List</h1>
        <BookList />
        <AddBook />
      </div>
    </ApolloProvider>
  );
}

export default App;

queries.js:

import { gql } from "apollo-boost";

const getBooksQuery = gql`
  {
    books {
      name
      id
    }
  }
`;

const getAuthorsQuery = gql`
  {
    authors {
      name
      id
    }
  }
`;

const addBookMutation = gql`
  mutation {
    addBook(name: "", genre: "", authorId: "") {
      name
      id
    }
  }
`;

export { getAuthorsQuery, getBooksQuery, addBookMutation };

AddBooks.js:

import React, { Component } from "react";
import { graphql } from "react-apollo";
import { compose } from "recompose";
// import * as compose from "lodash";
import { getAuthorsQuery, addBookMutation } from "../queries/queries";

class AddBook extends Component {
  state = {
    name: "",
    genre: "",
    authorId: ""
  };

  displayAuthors = () => {
    let data = this.props.data;
    if (data.loading) {
      return <option>loading authors...</option>;
    } else {
      return data.authors.map(author => {
        return (
          <option key={author.id} value={author.id}>
            {author.name}
          </option>
        );
      });
    }
  };

  submitForm(e) {
    e.preventDefault();
    console.log(this.state);
  }

  render() {
    return (
      <form onSubmit={this.submitForm.bind(this)}>
        <div className="field">
          <label>Book name: </label>
          <input
            type="text"
            onChange={e => {
              this.setState({ name: e.target.value });
            }}
          />
        </div>
        <div className="field">
          <label>Genre: </label>
          <input
            type="text"
            onChange={e => {
              this.setState({ genre: e.target.value });
            }}
          />
        </div>
        <div className="field">
          <label>Author: </label>
          <select
            onChange={e => {
              this.setState({ authorId: e.target.value });
            }}
          >
            <option>Select author</option>
            {this.displayAuthors()}
          </select>
        </div>
        <button>+</button>
      </form>
    );
  }
}

export default compose(
  graphql(getAuthorsQuery, { name: "getAuthorsQuery" }),
  graphql(addBookMutation, { name: "addBookMutation" })
)(AddBook);

I expected compose to be imported from react-apollo and to take the query and mutation and make them available inside of AddBook's props, so I can use them in the displayAuthors() and submitForm() funtions, but instead I get the error that it is not exported from react-apollo, and when I try the suggested solutions I found online I get the other errors mentioned above.



Solution 1:[1]

compose was removed from React Apollo 3 (see the Breaking Changes). Now, to use compose, use lodash's flowRight.

Install flowright:

yarn add lodash.flowright

Replace in your code:

import { compose } from 'react-apollo'

by

import {flowRight as compose} from 'lodash';

Solution 2:[2]

Below is how I solved this issue with my project:

  1. install lodash.flowright

    npm install lodash.flowright

  2. import it in your AddBook.js or in the file that you want to use compose

    import compose from 'lodash.flowright'

Solution 3:[3]

This can be solved by ;

npm install lodash.flowright
import * as compose from 'lodash.flowright';

Because compose is literally the same as flowRight, the apollo team decided to reduce the bundle size by removing it.

For more info read the breaking changes section here https://github.com/apollographql/react-apollo/blob/e9190fac891dd7af3a1690a5d2a1305953fd5a6f/Changelog.md#breaking-changes

Solution 4:[4]

The problem is not with compose. whenever we compose 2 or more queries we don't get "data" property you should try

let data = this.props.getAuthorsQuery;

Solution 5:[5]

same here I try to follow his tutorial "https://www.youtube.com/watch?v=rHw0_A4SJxo&list=PL4cUxeGkcC9iK6Qhn-QLcXCXPQUov1U7f&index=31", and stuck at the compose site here is how I fix it: - install lodash : npm lodash - import flowRight :

import React, { Component } from 'react';
//import { compose } from "recompose";
import {flowRight as compose} from 'lodash';
import {graphql} from 'react-apollo';
import {getAuthorsQuery,addBookMutation} from '../queries/queries';

Solution 6:[6]

import React, {Component} from 'react';
import {getAuthersQuery , AddBookMutation } from '../quearies/quearies'

import { gql } from 'apollo-boost'            

import { graphql } from 'react-apollo'        
import {flowRight as compose} from 'lodash';   

Solution 7:[7]

This Is how I got it working without using Compose.

I used useQuery to Query the authors and then used graphql to Mutate. Simply avoiding to nest Queries, which required using compose.

Its just a way to get around Compose (avoiding) and get the tutorials going, time is of great essence

import {useQuery} from "@apollo/react-hooks";
import React, {useState} from "react";
import {getAuthorsQuery, addBookMutation} from "../queries/queries.js";
import { graphql } from "react-apollo";
// import { flowRight as compose } from "lodash";
// import {* as compose} from "lodash.flowRight";


const AddBook = (props) => {
const [formData, setFormData] = useState({
    name : "",
    genre : "",
    authorId : ""
});

const authorsData = useQuery(getAuthorsQuery);


function displayAuthors(){

    console.log(authorsData)

    if(authorsData.loading){
        return( <option disabled >Loading Authors...</option> )
    }
    else{
        return( authorsData.data.authors.map(author => {
            return( <option key={author.id} value={author.id}>{author.name}</option>)
        }))
    }
}

function submitForm(e){
    e.preventDefault();
    console.log(formData);
}
    
return(
        <form id="add-book" onSubmit={(e) => submitForm(e)}>
            <div className="field" >  
                <label>Book Name:</label>
                <input type="text" onChange={(e) => setFormData({name : 
e.target.value})}/>
            </div>

            <div className="field" >  
                <label>Genre:</label>
                <input type="text" onChange={(e) => setFormData({genre : 
e.target.value})}/>
            </div>

            <div className="field" >  
                <label>Author:</label>
                <select onChange={(e) => setFormData({authorId : e.target.value})}>
                    <option>Select Author</option>
                    {displayAuthors()}
                </select>
            </div>

        <button>+</button>
    </form>
)}
export default graphql(addBookMutation)(AddBook);

I hope this help you finish up you graphql tutorials, but if you are looking into solving compose issues? Well I'm also struggling with that.

Solution 8:[8]

wow i am also doing the same project from the net ninja youtube tutorial and got the same error actually the version of react-oppollo is changed with the passage of time

Solution 9:[9]

You don't have to use lodash at least for this problem

Simply nest graphql function

export default graphql(addBookMutation)(graphql(getAuthorsQuery)(AddBook))

You can refer this

Apollo concepts

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Alan
Solution 2
Solution 3 Roninho
Solution 4 Keval Solanki
Solution 5 Forcesaj
Solution 6 Roberto Caboni
Solution 7 Gesy Darati
Solution 8 Dilawar Khan
Solution 9 Pankaj Garg