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 javascript : Sélectionner tout - Visualiser dans une fenêtre à part
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 javascript : Sélectionner tout - Visualiser dans une fenêtre à part 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 elm : Sélectionner tout - Visualiser dans une fenêtre à part
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 elm : Sélectionner tout - Visualiser dans une fenêtre à part
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 elm : Sélectionner tout - Visualiser dans une fenêtre à part
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)
le HTML (un template qui est appelé)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
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::
Partager