Closed ryanwk closed 7 years ago
Are you currently getting an error when trying to run this updateGame
function? Or is the issue that you aren't sure how to trigger this request?
Look at the game project api for what data the api is expecting for an update or PATCH. That would be a good place to start.
So based on what we talked about:
In your toggleTurn
function, you need to have access to 3 variables in order to make the PATH request: The letter that was placed, the index of the cell that was clicked, and whether the game is over or not.
Once you have these variables, you can build up a data
object with them.
You can then call api.updateGame
with the data object you have created.
Any progress @ryanwk ?
Yes, I did what ben said. My console logs dont confirm that data is being updated. How can I confirm that the patch request is working?
if you open up the dev tools in chrome, there is a Network tab that you can click. you should then see a stack of the requests that you've made to the API. I believe the bottom one is the latest one, so if you click that it should show you some more information about the request like this.
Request URL:https://github.com/settings/replies?context=issue
Request Method:GET
Status Code:200 OK
Remote Address:192.30.255.113:443
Referrer Policy:no-referrer-when-downgrade
If it says PATCH and 200 OK then hooray!
The console logs are not displaying for the functions that create and update a game and handle the subsequent post / patch requests.
When I check the network tab I get 200's except for the most recent on called 'websocket'.
network tab:
?credentials%5Bemail%5D=&credentials%5Bpassword%5D= vendor.js application.js info?t=1498776429463 websocket
what 'websocket' says:
Request URL:ws://localhost:7165/sockjs-node/720/fpvdghfu/websocket Request Method:GET Status Code:101 Switching Protocols
api.js file
const updateGame = function (data) {
console.log('update game is being invoked')
return $.ajax({
url: config.apiOrigin + '/games/' + store.game.id,
method: 'PATCH',
headers: {
Authorization: 'Token token=' + store.user.token
},
data
})
}
const createGame = function (data) {
console.log('creategame is being invoked')
return $.ajax({
url: config.apiOrigin + '/games/',
method: 'POST',
headers: {
Authorization: 'Token token=' + store.user.token
},
data
})
}
events.js file:
const onUpdateGame = function (letter, index, gameOver) {
console.log('onUpdateGame is being invoked')
const data = {
'game': {
'cell': {
'index': index,
'value': letter
},
'over': gameOver
}
}
api.updateGame(data)
.then(ui.updateGameSuccess)
.catch(ui.failure)
}
ui.js file:
const updateGameSuccess = () => {
// handle success
console.log('game has been updated with index, letter placed, and game status')
}
const failure = () => {
// handle failure
console.log('the request did not work!')
}
my console logs do work for this function but don't work for the update / create game functions.
events.js file:
// invoked with a click on a cell of the gameboard, places a symbol in the corresponding cell, updates the gameState array with a new value, update boolean to switch players turn
const toggleTurn = function (event) {
index = $(event.target).attr('id')
console.log('this is index: ' + index)
if (gameState[this.id] === 0) {
if (xTurn) {
$(this).text('X')
xTurn = false
gameState[this.id] = 1
if (checkForWin(1)) {
alert('X wins!')
gameOver = true
console.log('this is gameOver: ' + gameOver)
}
} else {
$(this).text('O')
xTurn = true
index = $(event.target.id)
gameState[this.id] = 2
if (checkForWin(2)) {
alert('O wins!')
gameOver = true
console.log('this is gameOver: ' + gameOver)
}
}
letter = $(this).text()
console.log('this is letter: ' + letter)
}
if (turnCounter++ === 8) {
alert('draw!')
gameOver = true
}
console.log(turnCounter)
console.log('this is gameOver: ' + gameOver)
// onUpdateGame(letter, index, gameOver)
}
Oh man.. I think I know what it is. toggleTurn had the function that invokes onUpdateGame commented out. Let's see if this works...
Ok good news, they are being invoked.... but now a new issue..
error message:
onUpdateGame is being invoked update game is being invoked 19:08:35.129 api.js:52 Uncaught TypeError: Cannot read property 'id' of undefined at Object.updateGame (api.js:52) at onUpdateGame (events.js:97) at HTMLDivElement.toggleTurn (events.js:63) at HTMLDivElement.dispatch (jquery.js:5206) at HTMLDivElement.elemData.handle (jquery.js:5014)
error source:
const updateGame = function (data) {
console.log('update game is being invoked')
return $.ajax({
url: config.apiOrigin + '/games/' + store.game.id,
method: 'PATCH',
headers: {
Authorization: 'Token token=' + store.user.token
},
data
})
}
and there's more.. when I try to sign out:
api.js:40 Uncaught TypeError: Cannot read property 'id' of undefined
at Object.signOut (api.js:40)
at HTMLDivElement.
line 40: url: config.apiOrigin + '/sign-out/' + store.user.id,
is this the local or deployed app?
local? how can I tell?
in the browser are you at localhost or github.io
localhost
alright are you still able to sign up and sign in?
So I just signed in, signed up, started a game, and started playing a game. 'I removed .id from lines 40 and 52' to see if that might be the issue.
This is what I've got:
network: Request URL:https://aqueous-atoll-85096.herokuapp.com/games/undefined Request Method:PATCH Status Code:404 Not Found Remote Address:54.225.138.206:443 Referrer Policy:no-referrer-when-downgrade
events.js:
const onUpdateGame = function (letter, index, gameOver) {
console.log('onUpdateGame is being invoked')
const data = {
'game': {
'cell': {
'index': index,
'value': letter
},
'over': gameOver
}
}
api.updateGame(data)
.then(ui.updateGameSuccess)
.catch(ui.failure)
}
api.js:
const updateGame = function (data) {
console.log('update game is being invoked')
return $.ajax({
url: config.apiOrigin + '/games/' + store.game,
method: 'PATCH',
headers: {
Authorization: 'Token token=' + store.user.token
},
data
})
}
console:
19:14:22.943 api.js:18 Object {credentials: Object} 19:14:23.241 ui.js:9 user has signed up [object Object] 19:14:34.929 api.js:28 Object {credentials: Object} 19:14:35.081 ui.js:13 user has signed in: [object Object] 19:14:40.919 api.js:61 creategame is being invoked 19:14:47.997 events.js:32 this is index: 0 19:14:47.998 events.js:55 this is letter: X 19:14:47.998 events.js:61 1 19:14:47.999 events.js:62 this is gameOver: false 19:14:47.999 events.js:87 onUpdateGame is being invoked 19:14:47.999 api.js:50 update game is being invoked 19:14:48.100 ui.js:27 the request did not work!
look at the URL for the PATCH request
https://aqueous-atoll-85096.herokuapp.com/games/undefined
can you post your function for handling the successful creation of a new game?
I don't have a success function in my ui.js for creating a new game. but heres the createGame function in my api.js file:
const createGame = function (data) {
console.log('creategame is being invoked')
return $.ajax({
url: config.apiOrigin + '/games/',
method: 'POST',
headers: {
Authorization: 'Token token=' + store.user.token
},
data
})
}
not sure if it's relevant but here's the success function for when a user signs in:
const signInSuccess = (data) => {
// handle success
console.log('user has signed in: ' + data)
store.user = data.user
}
so notice how in signInSuccess we get a data
object back that has a user
object inside it. We save that user
object inside of our store
so we can use its id
, among other things.
if you're not already, you should be doing something similar with the data
object that gets returned to us from successfully creating a new game. does this help?
Yes, makes sense. I just created this variable
would I want something like 'store.game = data.game' ?
const createGameSuccess = (data) => {
// handle success
console.log('user has signed in: ' + data)
store.game = data.game
}
and then the createGame function would have something like this?
const createGame = function (data) {
console.log('creategame is being invoked')
return $.ajax({
url: config.apiOrigin + '/games/' + store.game,
method: 'POST',
headers: {
Authorization: 'Token token=' + store.user.token
},
data
})
}
ok, so signed-up, signed-in, started game but it breaks when the createGame function is invoked.
const createGame = function (data) {
console.log('creategame is being invoked')
return $.ajax({
url: config.apiOrigin + '/games/' + store.game,
method: 'POST',
headers: {
Authorization: 'Token token=' + store.user.token
},
data
})
.done(ui.createGameSuccess)
.fail(ui.failure)
}
const createGameSuccess = (data) => {
// handle success
console.log('user has signed in: ' + data)
store.game = data.game
}
const failure = () => {
// handle failure
console.log('the request did not work!')
}
heres the API docs for how you should build a POST request to create a game:
POST /games
what URL are you trying to hit in your createGame function?
url: config.apiOrigin + '/games/' + store.game,
looks like you're adding something to the end you don't need
remember the game doesn't have an id associated with it until it is created on the back end
I sat down with Jess earlier and this was the only way it would work, if I set up config like so:
const config = { apiOrigins: { development: 'https://aqueous-atoll-85096.herokuapp.com', production: 'https://aqueous-atoll-85096.herokuapp.com' } } module.exports = config
Ok, makes sense, I'll try removing 'store.game'.
ok, that worked, now I can create a game but it breaks when we get to updateGame:
const updateGame = function (data) {
console.log('update game is being invoked')
return $.ajax({
url: config.apiOrigin + '/games/' + store.game,
method: 'PATCH',
headers: {
Authorization: 'Token token=' + store.user.token
},
data
})
}
const createGame = function (data) {
console.log('creategame is being invoked')
return $.ajax({
url: config.apiOrigin + '/games/',
method: 'POST',
headers: {
Authorization: 'Token token=' + store.user.token
},
data
})
.done(ui.createGameSuccess)
.fail(ui.failure)
}
ui.js :
const signInSuccess = (data) => {
// handle success
console.log('user has signed in: ' + data)
store.user = data.user
}
const signOutSuccess = () => {
// handle success
console.log('user has signed out')
store.user = {}
}
const updateGameSuccess = () => {
// handle success
console.log('game has been updated with index, letter placed, and game status')
}
const createGameSuccess = (data) => {
// handle success
console.log('game has been created: ' + data)
store.game = data.game
}
const failure = () => {
// handle failure
console.log('the request did not work!')
}
error message: api.js:28 Object {credentials: Object} 19:51:33.525 ui.js:13 user has signed in: [object Object] 19:51:36.610 api.js:61 creategame is being invoked 19:51:36.701 ui.js:27 game has been created: [object Object] 19:51:40.308 events.js:32 this is index: 0 19:51:40.310 events.js:55 this is letter: X 19:51:40.310 events.js:61 1 19:51:40.310 events.js:62 this is gameOver: false 19:51:40.311 events.js:87 onUpdateGame is being invoked 19:51:40.311 api.js:50 update game is being invoked 19:51:40.405 ui.js:32 the request did not work!
network tab:
Request URL:https://aqueous-atoll-85096.herokuapp.com/games/[object%20Object] Request Method:PATCH Status Code:404 Not Found Remote Address:23.23.196.129:443 Referrer Policy:no-referrer-when-downgrade
Almost There!!
This is the URL you are sending the PATCH to:
url: config.apiOrigin + '/games/' + store.game
Do you see what we might need to add to the end?
store.game is being turned into a string of [object Object]...so maybe that object has something inside of it that we want to utilize, like we did with store.user.?
as a reminder the API docs say that we should send a PATCH request to /games/:id
it worked!!!!! I added '.id' to the end of that PATCH URL.
console: api.js:50 updateGame is being invoked 20:03:14.355 ui.js:23 game has been updated with index, letter placed, and game status
network: Request URL:https://aqueous-atoll-85096.herokuapp.com/games/7262 Request Method:PATCH Status Code:200 OK Remote Address:23.23.171.171:443 Referrer Policy:no-referrer-when-downgrade
Thank you!!!!
no!!! it broke again!!
Object {credentials: Object} 20:03:09.632 ui.js:13 user has signed in: [object Object] 20:03:12.406 api.js:61 createGame is being invoked 20:03:12.519 ui.js:27 game has been created: [object Object] 20:03:14.246 events.js:32 this is index: 0 20:03:14.248 events.js:55 this is letter: X 20:03:14.248 events.js:61 1 20:03:14.249 events.js:62 this is gameOver: false 20:03:14.249 events.js:87 onUpdateGame is being invoked 20:03:14.250 api.js:50 updateGame is being invoked 20:03:14.355 ui.js:23 game has been updated with index, letter placed, and game status 20:06:54.423 events.js:32 this is index: 1 20:06:54.423 events.js:55 this is letter: O 20:06:54.424 events.js:61 2 20:06:54.424 events.js:62 this is gameOver: false 20:06:54.424 events.js:87 onUpdateGame is being invoked 20:06:54.425 api.js:50 updateGame is being invoked 20:06:59.782 jquery.js:8430 Uncaught TypeError: Illegal invocation at add (jquery.js:8430) at buildParams (jquery.js:8417) at buildParams (jquery.js:8411) at buildParams (jquery.js:8411) at buildParams (jquery.js:8411) at buildParams (jquery.js:8411) at buildParams (jquery.js:8411) at buildParams (jquery.js:8411) at Function.jQuery.param (jquery.js:8450) at Function.ajax (jquery.js:9040) add @ jquery.js:8430 buildParams @ jquery.js:8417 buildParams @ jquery.js:8411 buildParams @ jquery.js:8411 buildParams @ jquery.js:8411 buildParams @ jquery.js:8411 buildParams @ jquery.js:8411 buildParams @ jquery.js:8411 jQuery.param @ jquery.js:8450 ajax @ jquery.js:9040 updateGame @ api.js:51 onUpdateGame @ events.js:97 toggleTurn @ events.js:63 dispatch @ jquery.js:5206 elemData.handle @ jquery.js:5014 20:07:09.409 events.js:32 this is index: 2 20:07:09.410 events.js:55 this is letter: X 20:07:09.410 events.js:61 3 20:07:09.410 events.js:62 this is gameOver: false 20:07:09.411 events.js:87 onUpdateGame is being invoked 20:07:09.411 api.js:50 updateGame is being invoked 20:07:09.705 ui.js:23 game has been updated with index, letter placed, and game status 20:07:12.171 events.js:32 this is index: 3 20:07:12.172 events.js:55 this is letter: O 20:07:12.172 events.js:61 4 20:07:12.173 events.js:62 this is gameOver: false 20:07:12.173 events.js:87 onUpdateGame is being invoked 20:07:12.173 api.js:50 updateGame is being invoked 20:08:19.988 jquery.js:8430 Uncaught TypeError: Illegal invocation at add (jquery.js:8430) at buildParams (jquery.js:8417) at buildParams (jquery.js:8411) at buildParams (jquery.js:8411) at buildParams (jquery.js:8411) at buildParams (jquery.js:8411) at buildParams (jquery.js:8411) at buildParams (jquery.js:8411) at Function.jQuery.param (jquery.js:8450) at Function.ajax (jquery.js:9040)
@jordanallain X's work fine but when it's O's turn it breaks!
20:06:59.782 jquery.js:8430 Uncaught TypeError: Illegal invocation at add (jquery.js:8430)
drop a debugger in there, step through line by line so you can see at which line it is breaking
alright, debuggers in, refreshed the page ..everything works fine sign-in, start game, on X's turn it works, but when we switch to O's turn and upon clicking it breaks. This is what I get:
jquery.js:8430 Uncaught TypeError: Illegal invocation at add (jquery.js:8430) at buildParams (jquery.js:8417) at buildParams (jquery.js:8411) at buildParams (jquery.js:8411) at buildParams (jquery.js:8411) at buildParams (jquery.js:8411) at buildParams (jquery.js:8411) at buildParams (jquery.js:8411) at Function.jQuery.param (jquery.js:8450) at Function.ajax (jquery.js:9040)
in the sources tab: // If value is a function, invoke it and use its return value var value = jQuery.isFunction( valueOrFunction ) ? valueOrFunction() : valueOrFunction;
s[ s.length ] = encodeURIComponent( key ) + "=" +
encodeURIComponent( value == null ? "" : value );
};
there's an error on line 8430 here valueOrFunction() :
can you post the function that runs every time you click? and if possible, the function that is deciding that its O's turn or placing the O.
let xTurn = true
let gameState = [0, 0, 0, 0, 0, 0, 0, 0, 0]
let turnCounter = 0
let index = ''
let letter = ''
let gameOver = false
// event listeners
const addHandlers = function () {
$('.game-cell').on('click', toggleTurn)
$('#resetButton').on('click', resetBoard)
}
// invoked with a click on a cell of the gameboard, places a symbol in the corresponding cell, updates the gameState array with a new value, update boolean to switch players turn
const toggleTurn = function (event) {
index = $(event.target).attr('id')
console.log('this is index: ' + index)
if (gameState[this.id] === 0) {
if (xTurn) {
$(this).text('X')
xTurn = false
gameState[this.id] = 1
if (checkForWin(1)) {
alert('X wins!')
gameOver = true
console.log('this is gameOver: ' + gameOver)
}
} else {
$(this).text('O')
xTurn = true
index = $(event.target.id)
gameState[this.id] = 2
if (checkForWin(2)) {
alert('O wins!')
gameOver = true
console.log('this is gameOver: ' + gameOver)
}
}
letter = $(this).text()
console.log('this is letter: ' + letter)
}
if (turnCounter++ === 8) {
alert('draw!')
gameOver = true
}
console.log(turnCounter)
console.log('this is gameOver: ' + gameOver)
onUpdateGame(letter, index, gameOver)
debugger
}
I was storing letter as this: letter = $(this).text() should have been this: letter = 'X'
I need help getting started with storing the state of my game, general planning, etc. I'm not sure how to approach this.
I think what I need is a patch request?
my goal is to: keep the server informed of anything that happens with the game (when an x or o is placed on the board, who's turn it is, games played, etc.)
in order to fulfill this MVP requirement: Communicate with a back-end to store the state of your game.
I've been trying to simulate Ingrid's code:
I've read through these relevant issues and documentation: https://git.generalassemb.ly/ga-wdi-boston/game-project-api https://github.com/ga-wdi-boston/game-project/issues/825 https://github.com/ga-wdi-boston/game-project/issues/800