Giter Site home page Giter Site logo

js-tictactoe-rails-api-v-000's Introduction

jQuery Tic-Tac-Toe with a Rails API — Part 2

Congratulations on setting up your Rails API back-end! Hopefully you took a short break to celebrate because the real fun starts now.

In this second installment, you're tasked with building out a JavaScript front-end to place on top of the Rails API we created in the previous exercise. For reference, here's the video showing how the final product should function. (Right-click and Save Link As... to download.)

Objectives

  • Create a fully-functional tic-tac-toe game using jQuery and/or vanilla JavaScript.
  • Make AJAX requests to a Rails API in order to save, update, and reload games.

Getting started

Code your solution in app/assets/javascripts/tictactoe.js, which we're loading via the Rails asset pipeline. As a refresher, we added that file to the asset pipeline by specifying //= require tictactoe in our JavaScript manifest file (app/assets/javascripts/application.js).

You are welcome to use jQuery, pure JavaScript, or a combination of the two, but you should not have to create any new files or modify anything outside of tictactoe.js.

Exploring the DOM

The only view our application requires lives in app/views/home/index.html. Before you dive into writing JavaScript, start the Rails server and familiarize yourself with the DOM that you'll be working with. Take special note of the way in which the squares of the game board are identified with data-x and data-y attributes.

Buttons!

button#save

Clicking this button should save the current game state. If the current game already exists in the database, saving it should update that previously-saved game. If the current game has not yet been persisted to the database, saving it should do so. As a brief example, if we start with a blank board that has not been saved and click button#save, the current game should be persisted to our database. If we then click button#save a second time, the persisted game should be updated (though, since we have yet to make any moves, the board will still be blank in the updated game state).

button#previous

Clicking this button should grab all of the persisted games from the database and create a button for each that, when clicked, returns that saved game's state to our tic-tac-toe board. All of the buttons should be added to the div#games element in the DOM.

button#clear

Clicking this button should clear the game board and start a completely new game. If we click button#save, then button#clear, and then button#save again, two games should have been persisted to the database.

Conjunction junction, what's your function?

For the actual TTT functionality, the test suite is pretty opinionated. We've given you a lot of the structure, and the tests force you down a pretty specific path as far as which functions you need to define and what they should do:

  • player()
    • Returns the token of the player whose turn it is, 'X' when the turn variable is even and 'O' when it is odd.
  • updateState()
    • Invokes player() and adds the returned string ('X' or 'O') to the clicked square on the game board.
  • setMessage()
    • Accepts a string and adds it to the div#message element in the DOM.
  • checkWinner()
    • Returns true if the current board contains any winning combinations (three X or O tokens in a row, vertically, horizontally, or diagonally). Otherwise, returns false.
    • If there is a winning combination on the board, checkWinner() should invoke setMessage(), passing in the appropriate string based on who won: 'Player X Won!' or 'Player O Won!'
  • doTurn()
    • Increments the turn variable by 1.
    • Invokes the updateState() function, passing it the element that was clicked.
    • Invokes checkWinner() to determine whether the move results in a winning play.
  • attachListeners()
    • Attaches the appropriate event listeners to the squares of the game board as well as for the button#save, button#previous, and button#clear elements.
    • When a user clicks on a square on the game board, the event listener should invoke doTurn() and pass it the element that was clicked.
    • NOTE: attachListeners() must be invoked inside either a $(document).ready() (jQuery) or a window.onload = () => {} (vanilla JavaScript). Otherwise, a number of the tests will fail (not to mention that your game probably won't function in the browser).
    • When you name your save and previous functions, make sure to call them something like saveGame() and previousGames(). If you call them save() and previous() you may run into problems with the test suite.

Testing

Note: Use var instead of let or const when defining variables in this lab. Due to compiler bugs, tests will fail to recognize working code.

You can run the test suite in one of two ways:

  1. With Node (in your terminal) by running the learn or npm test command.
  2. In the browser by opening up test/fixtures/index-test.html in your browser, opening the JS console, and invoking the mocha.run() method. Note that, on subsequent tests, you should refresh the page each time before invoking mocha.run().

Bonus(es)

  1. Once all of the tests are passing and you have a functionally awesome / awesomely functional tic-tac-toe game with persistence, try refactoring your front-end to use ES6 classes and other OO design patterns. Think about the domain you're trying to model — how many classes do you need? What are the relationships between classes?
  2. Implement a memoization scheme for minimizing the amount of database calls your application makes.
  3. Modify the GameSerializer to include the updated_at attribute, and display the last-updated time next to each saved game in the DOM.

Resources

View jQuery Tic Tac Toe on Learn.co and start learning to code for free.

js-tictactoe-rails-api-v-000's People

Contributors

annjohn avatar aturkewi avatar bhollan avatar blake41 avatar brennenawana avatar curiositypaths avatar dakotalmartinez avatar dependabot[bot] avatar gj avatar kthffmn avatar mendelb avatar peterbell avatar rrcobb avatar victhevenot avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

js-tictactoe-rails-api-v-000's Issues

Test inconsistency between browser moch.run() and learn in terminal

When testing in the browser and in the local terminal within this lab (js-tictactoe-rails-api-v-000) the test are not outputting the same number of test passing and failing.

Also console.log and debugger does not always hit the code when the test are being ran in the browser.

I ran the test using the following commands: learn and npm test

was stuck on an issue and found a problem

It seems in the Fixtures that are set up for the tests, there are a pre-played "X" and "O" on the board. This can cause inexplicable failures and you to stay up until 4am trying to find them.

Tests

Please correct me if I'm wrong but it doesn't seem like these two things can be true

it('Users cannot play any turns once a game is won or tied', () => { populateBoard(['X', 'X', 'X', '', '', '', 'O', 'O', '']); window.turn = 5;

it('resets the board and the "turn" counter when a game is won'

If the game resets when it is won, then the turn count would be 0, not 5.

npm test issues | tests not passing

When testing with 'npm test' (learn) in the Terminal while using ES6 "const" or "let", most test will fail. Would be good to update npm test to allow these test to pass or alert the users that these test will fail if you use ES6. When running test within the browser using "mocha.run" these test successfully pass.

Quick way to check this, is to change any of your initial 'tictactoe.js' file declared variables to const or let, then run npm test in Terminal. You will see that test will fail. Now run test utilizing the /test/fixtures/index-test.html file provided in repo and use mocha.run() to execute test. The tests will pass.

Var vs Let

Earlier in the curriculum we were taught explicitly to use 'let' instead of 'var'. I'm on my umpteenth lab that requires the use of var in order to pass the tests.

SecurityError: localStorage is not available for opaque origins

This part of the tests throws up the error in the title:
tictactoe.js attachListeners() passes the clicked-on <td> element to doTurn():

Apparently it's to do with changes to jest and can be fixed by adding testURL: 'http://localhost' to the jest config file somewhere in node_modules...if you can find it!

Thread here:

jestjs/jest#6766

Cannot run js tests

When running learn test only the controller tests run. Trying learn test spec/tictactoe.spec.js or rspec spec/tictactoe.spec.js renders this error:

$ rspec spec/tictactoe.spec.js 
/home/mm/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1361:in `load': /home/mm/code/labs/js-tictactoe-rails-api-v-000/spec/tictactoe.spec.js:14: `$(' is not allowed as a global variable name (SyntaxError)
/home/mm/code/labs/js-tictactoe-rails-api-v-000/spec/tictactoe.spec.js:14: syntax error, unexpected end-of-input, expecting '}'
      $(selector).click();
       ^
    from /home/mm/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1361:in `block in load_spec_files'
    from /home/mm/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1359:in `each'
    from /home/mm/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1359:in `load_spec_files'
    from /home/mm/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:106:in `setup'
    from /home/mm/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:92:in `run'
    from /home/mm/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:78:in `run'
    from /home/mm/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:45:in `invoke'
    from /home/mm/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/rspec-core-3.4.4/exe/rspec:4:in `<top (required)>'
    from /home/mm/.rbenv/versions/2.2.2/bin/rspec:23:in `load'
    from /home/mm/.rbenv/versions/2.2.2/bin/rspec:23:in `<main>'

ShanaLMoore reports that sudo learn works but this does not work for me on Ubuntu 14.04

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.