Décodage d'un message JSON par ELM
Bonjour,
J'espère que je suis au bon endroit pour parler de ELM/JSON/Python (Flask), Alors j'explique mon problème,
Après reception d'un message, Mon serveur essaye d'envoyer un retour à la vue ELM, en passant par JSON.
La console javascript reçois ceci:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
0:
currentPlayerId: "0"
firstClickCellId: "-1"
gameOverStatus: "1"
gamegrid: Array(9)
0: {hash: "0", value: "-1"}
1: {hash: "1", value: "-1"}
2: {hash: "2", value: "-1"}
3: {hash: "3", value: "-1"}
4: {hash: "4", value: "-1"}
5: {hash: "5", value: "-1"}
6: {hash: "6", value: "-1"}
7: {hash: "7", value: "-1"}
8: {hash: "8", value: "-1"}
length: 9
__proto__: Array(0)
userToPlayId: "1"
__proto__: Object
length: 1
__proto__: Array(0) |
Mais à ma grande surprise, j'ai ce message juste après:
Code:
Decode error: Failure "Expecting an OBJECT with a field named `gamegrid`" <internals>
Pourtant le champ "gamegrid" est bien présent dans le message reçu!
En gros voilà le tout du problème, je vous met le code pour que vous puissiez voir ce qui est fait avant
======================================ANNEXE============================================================
Voici une partie de mon modèle:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
type alias Model =
{
users : List User
, gameOverView: GameOverView
}
type alias GameOverView =
{
gameGrid: List Cell
,userToPlayId: String
,gameOverStatus : String
,firstClickCellId: String
, currentPlayerId : String
}
type alias Cell =
{
hash: String
,value: String
} |
Voici mon décodeur de cette partie
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
cellDecoder : Decoder Cell
cellDecoder =
Decode.map2 Cell
(Decode.field "hash" Decode.string)
(Decode.field "value" Decode.string)
listCellDecoder : Decoder (List Cell)
listCellDecoder =
Decode.list cellDecoder
gameOverViewDecoder : Decoder GameOverView
gameOverViewDecoder =
Decode.map5 GameOverView
(Decode.field "gamegrid" listCellDecoder)
(Decode.field "userToPlayId" Decode.string)
(Decode.field "gameOverStatus" Decode.string)
(Decode.field "firstClickCellId" Decode.string)
(Decode.field "currentPlayerId" Decode.string) |
Voici le décodeur JSON
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
decodeExternalGameOverView : Value -> Msg
decodeExternalGameOverView val =
case Decode.decodeValue gameOverViewDecoder val of
Ok gameOverView ->
GotNewGameOverView gameOverView
Err err ->
DecodeError err
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.batch
[ userlistPort decodeExternalUserlist,
gameOverViewlistPort decodeExternalGameOverView,
receiveData ReceivedDataFromJS] |
Et le serveur qui envoie le message (noter qu'il y'a un message précedent qui est bien reçu, ici je ne m'interesse qu'à ce que j'envoie)
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
@app.route('/updategrid/', methods=['POST'])
@flask_login.login_required
def checkPlay():
print("+++++++++++++++++++++++")
firsCellClikId = request.json["firstClickedId"]
secondCellClikId = request.json["secondClickedId"]
userToPlayId = request.json["userToPlay"]
currentPlayerId = request.json["currentPlayerId"]
gameOverStatus = "1"
g = []
for i in range(9):
grid = {}
grid["hash"] = str(i)
grid["value"] = request.json[str(i)]
g.append(grid)
print("checking play turn")
print("firstCell = ", firsCellClikId, " SecondCell = ", secondCellClikId)
print("UserToplay = ", userToPlayId, " UserPlayed = ", currentPlayerId)
if(userToPlayId == "0"):
userToPlayId = "1"
else:
userToPlayId = "0"
#for x, y in g.items():
send = {
"gamegrid": g,
"userToPlayId": userToPlayId,
"gameOverStatus": gameOverStatus,
"firstClickCellId": "-1",
"currentPlayerId": currentPlayerId
}
print(send)
io.emit('gamegrid', [
send,
]
, broadcast=True)
print("New grid sent")
return "ok", 201 |
le HTML (un template qui est appelé)
Code:
1 2 3 4 5 6 7 8 9 10 11
|
<script src="//cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js" integrity="sha256-yr4fRk/GU1ehYJPAs8P4JlTgu0Hdsp4ZKrx8bDEDC3I=" crossorigin="anonymous"></script>
<script type="text/javascript" charset="utf-8">
var socket = io();
var app = Elm.Main.init({ node: document.querySelector('#main-content')});
socket.on('gamegrid', function(gamegrid){
console.log("New GameOverView received:", gamegrid);
app.ports.gameOverViewlistPort.send(gamegrid);
}); |
Recap: le problème reste le suivant: la console javascript (ou plutôt le decodeur elm) ne trouve pas le champ "gamegrid" alors qu'il est présent et correspond au type attendu (liste de Cell)
Vos suggestions seront les bienvenues .
Best regards::