Reputation: 117
I have just started working with Apollo on my side project (web game) and got stuck on some of the subscriptions I use.
In some views the subscription doesn't run directly, but it works as expected if I refresh the page.
// StartGame.vue
<script>
import store from "../store/index";
export default {
data() {
return {
players: [],
game: null
};
},
methods: {
async onStartGame() {
const response = await this.$store.dispatch("updateGame", {
started: true
});
if (!response) {
alert("Something went wrong. Try again");
return;
}
this.$router.push({ name: "GameProgress" });
},
onGoToGame() {
this.$router.push({ name: "GameProgress" });
}
},
mounted() {
this.game = this.$store.getters.getGame;
},
created() {
this.$apollo.subscriptions.gameAndPlayers.refresh();
},
apollo: {
$subscribe: {
gameAndPlayers: {
query: require("../graphql/subscriptions/subscribeGameAndPlayers.gql"),
variables: {
game_id: store.getters.getGame.id
},
result(data) {
console.log("subscribeGameAndPlayers", data);
const game = data.data.game;
this.game = { ...this.game, started: game.started };
this.players = game.players;
}
}
}
}
};
</script>
Can someone see something obvious wrong with this piece of code? As I wrote, if I refresh this page the subscription starts to work (players join the game from other browsers). I guess mounted and created isn't needed if I can get the apollo part to work, right?
I thought it's probably some cache since Apollo seems to use it a lot, and I don't have much knowledge about it yet.
Tried to add fetchPolicy: 'no-cache' without success
// apollo.js (included in main.js)
export default new ApolloClient({
link: link
cache: new InMemoryCache(),
defaultOptions: {
fetchPolicy: "no-cache"
}
});
A few more views have the same behavior so I guess it's something fundamental I'm missing..
Upvotes: 1
Views: 1328
Reputation: 117
I solved my problem. I was missing some fundamentals about vue-apollo as I thought..
In apollo, I fetch my data with a query first, and then add the subscription by subscribeToMore
There is probably a better way, but here is the working code:
//start game
<script>
import store from "../store/index";
export default {
data() {
return {
gameAndPlayers: null,
loading: 0
};
},
methods: {
async onStartGame() {
const response = await this.$store.dispatch("updateGame", {
started: true
});
if (!response) {
alert("Something went wrong. Try again");
return;
}
this.$router.push({ name: "GameProgress" });
},
onGoToGame() {
this.$router.push({ name: "GameProgress" });
}
},
apollo: {
gameAndPlayers: {
query: require("../graphql/queries/getGameAndPlayers.gql"),
variables() {
return {
id: store.getters.getGame.id
};
},
update(data) {
return { ...data.game };
},
subscribeToMore: [
{
document: require("../graphql/subscriptions/subscribeGameAndPlayers.gql"),
variables() {
return {
game_id: store.getters.getGame.id
};
},
updateQuery: (previous, { subscriptionData }) => {
return { ...subscriptionData.data };
}
}
]
}
}
};
</script>
I hope this might help someone else with the same problem.
Upvotes: 2