Can you update existing data with an Array of objects using a mutation serverside with Apollo GraphQL?

370 views Asked by At

Little background:

I'm building a Fantasy FPL App for my colleagues at work so we can have our own app with our own data and league. I'm using Vue.js on the FE and GraphQL + Apollo + MongoDB for the BE.

To clarify the question: I want to update my DB with data that is fetched from an external REST API using a mutation on the backend if possible.

So I've manually added some initial data to the DB(some of it does not exist in the external API like player avatars), and I want to now update some of the existing data fields through a Query to an external REST API. Namely points, rank, total points etc.

I've successfully made the Query to get the data from the REST API, and reduced it using Apollos RESTDataSource that I found in the Apollo docs here:


class LeagueAPI extends RESTDataSource {
  constructor() {
    super();
    this.baseURL = 'https://fantasy.premierleague.com/api/leagues-classic/xxxxxx/standings/';
  }
  // Makes sure we can call the API(necessary headers)
  willSendRequest(request) {
    request.headers.set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36");
  }
  
 // Reduces data
  leagueReducer(league) {
    return {
      player_id: league.entry || 0,
      total: league.total,
      player_name: league.player_name,
      rank: league.rank,
      previous_rank: league.last_rank,
      points: league.event_total,
      team_name: league.entry_name
    }
  }
  // Get's total league data standings for current season
  async getLeagueData() {
    try {
      const response  = await this.get('');
      const extractedResponse = response.standings.results
      return Array.isArray(extractedResponse)
      ? extractedResponse.map(league => this.leagueReducer(league))
      : [];
    }
    catch(error) {
      console.log('Error in getLeagueData', error)
    }
  }
}

module.exports = LeagueAPI

In my response I get an Array with objects that I want to iterate over and update the DB accordingly so that the newest data is always displayed after a match.

Example of an object in the array:

 {
     "id": 57643299,
     "event_total": 71,
     "player_name": "John Doe",
     "rank": 1,
     "last_rank": 1,
     "rank_sort": 1,
     "total": 580,
     "entry": 10432744,
     "entry_name": "Amazing team name"
},

I have an updateGameWeek mutation that works when I use it in the Graphiql playground, but I'm wondering if there is a way to call a mutation on the backend?

And how would I do this since I need to iterate over it several times as there are many objects that need to be updated according to their corresponding ids on the backend.

Here's an example of an updateQuery that works:

mutation updateGameWeek{
  updateGameWeek(player_id: 29729805, input: {
    avatar:"somestring"
    player_id: 29324805
  })

This mutation correctly updates the players avatar by id, and it's basically the blueprint for what I want to use when I am updating the whole DB by player id's.

Here is also what a GameWeek Object looks like/defined as:

type GameWeek {
        avatar: String
        team_id: Int
        points: Float
        player_name: String
        rank: Int
        previous_rank: Int
        total: Float
        player_id: ID!
        team_name: String
    }

And also what the actual resolver for the mutation above looks like:

module.exports = async (_, { id, input }, { models }) => {
    try {
        const gameWeekToUpdate = await models.GameWeek.findOne({ _player_id: id });

        Object.keys(input).forEach(value => {
            gameWeekToUpdate[value] = input[value];
        });
        const updatedGameWeek = await gameWeekToUpdate.save();
        
        return updatedGameWeek;
    } catch (error) {
        console.log('Error in updateGameWeek Mutation', error)
    }
}
0

There are 0 answers