2017-01-20 1 views
1

서버에서 데이터를 반환하는 데 페치에 문제가있어 그 이유를 이해하지 못하는 것 같습니다.Fetch()가 응답으로 서버에서 데이터를 반환하지 않습니다.

서버가 JSON을 다시 보내기 전에 약속이 해결되어서 최근에 내 모델을 업데이트하여 약속을 활용할 수 있다고 생각했습니다. 나는 약속과 API를 가져 오는 것이 처음이에요.

내가 너무 콜백을 되돌릴 및 에 다시 Players.js 경로를 내 Player.findPlayer.create 방법을 넣어 모두 서버 측에서 약속을 피하기 위해 기꺼이.

플레이어 모델 (약속을 추가 한 후)

// require mongoose for data modeling 
import mongoose from 'mongoose'; 
import Q from 'q'; 

const Schema = mongoose.Schema; 

// define player schema 
const PLAYER_SCHEMA = new Schema({ 
    name: String, 
    score: Number 
}); 

PLAYER_SCHEMA.statics.createPlayer = (name, score) => { 
    const deferred = Q.defer(); 

    Player.create({ 
    name, 
    score, 
    }, (error, player) => { 
    if (error) { 
     deferred.reject(new Error(error)); 
    } 

    deferred.resolve(player); 
    }); 

    return deferred.promise; 
} 

PLAYER_SCHEMA.statics.getPlayers =() => { 
    const deferred = Q.defer(); 

    Player.find({}) 
    .sort({ 
     score: 'desc' 
    }) 
    .limit(5) 
    .exec((error, players) => { 
     if (error) { 
      deferred.reject(new Error(error)); 
     } 

     deferred.resolve(players); 
    }); 

    return deferred.promise; 
} 

let Player = mongoose.model('Player', PLAYER_SCHEMA); 

// first param is the singular name for the collection, 
// mongoose automatically looks for the plural version 
// so our db will have a 'players' collection 
export default Player; 

노선이 엔드 포인트 테스트

// dependencies 
import express from 'express'; 
import Player from '../models/player'; 

const ROUTER = express.Router(); 

ROUTER.post('/', (req, res) => { 
    const name = req.body.name; 
    const score = req.body.score; 
    const promise = Player.createPlayer(name, score); 

    promise.then((response) => { 
    res.status(201).json(response); 
    }).catch((err) => { 
    res.send(err) 
    }); 

}); 

ROUTER.get('/', (req, res) => { 
    const promise = Player.getPlayers(); 

    promise.then((response) => { 
    console.log(response); 
    res.status(200).json(response); 
    }).catch((err) => { 
    res.send(err) 
    }); 
}); 

export default ROUTER; 

는 우체부에서 잘 작동, 그래서 문제를 가정 (약속을 추가 한 후) 서버에 있지 않습니다.

여기에는 내가 문제가 있다고 생각됩니다. (AJAX 방식이 저장된)

Client.js

function createPlayer(playerData, onError, cb) { 
    return fetch('/api/players', { 
    method: 'post', 
    body: JSON.stringify(playerData), 
    headers: { 
     'Accept': 'application/json', 
     'Content-Type': 'application/json', 
    }, 
    }).then(checkStatus) 
    .then(cb) 
    .catch(onError); 
} 

function getPlayers(success, onError) { 
    return fetch('/api/players', { 
    headers: { 
     'Accept': 'application/json', 
     'Content-Type': 'application/json', 
    }, 
    }).then(checkStatus) 
    .then(parseJSON) 
    .then(success) 
    .catch(onError); 
} 

function checkStatus(response) { 
    if (response.status >= 200 && response.status < 300) { 
    return response; 
    } else { 
    const error = new Error(`HTTP Error ${response.statusText}`); 
    error.status = response.statusText; 
    error.response = response; 
    throw error; 
    } 
} 

function parseJSON(response) { 
    return response.json(); 
} 

const Client = { 
    createPlayer, 
    getPlayers 
}; 
export default Client; 

App.jsx (생략 많은 코드)

//는 다른 모든 코드

const playerData = { 
    name, 
    score: this.state.totalScore, 
    }; 

    client.createPlayer(playerData, 
    (err) => { 
     // TODO: improve error message 
     console.log(err); 
    }, 
    client.getPlayers((data) => { 
     // array of objects containing all but most recent entry 
     console.log(data); 
     this.setState({ 
     inputScreen: false, // hide the input screen 
     highScoreScreen: true, // show the high score screen 
     yeti: yetiWin, 
     highScores: [...this.state.highScores, ...data], 
     }); 
    }, (err) => { 
     // TODO: improve this error message 
     console.log(err); 
    }) 
); 
생략

// 다른 모든 코드는 누락되었습니다.

데이터 변수에는 새로 생성 된 플레이어가 포함되지 않지만 다른 플레이어가 포함됩니다. 따라서 생성 및 읽기 작업은 서버 측에서 수행됩니다. 나는 다음과 같은 것을 내 App.jsx을 수정하는 경우 :

App.jsx (재판)

const playerData = { 
    name, 
    score: this.state.totalScore, 
    }; 

    client.createPlayer(playerData, 
    (err) => { 
     // TODO: improve error message 
     console.log(err); 
    }, 
    (res) => { 
     // should contain something like: 
     // { 
     //  "__v": 0, 
     //  "_id": "5881922f441fda40ccc52f83", 
     //  "name": "player name", 
     //  "score": "123" 
     // } 
     // right? 
     console.log(res.json()); 
     console.log(res); 
     console.log(res.body); 
    } 
); 

내가 할 내가 res.jsonresres.body 로그 :

약속 {[[PromiseStatus ]] : '보류 중', [[PromiseValue]] : 정의되지 않음}

응답 {type : "basic", url : "http://localhost:3000/api/players ", 상태 : (200), 확인 : 사실,하는 statusText :"} ... "OK

ReadableStream {} 나는 우체부 내 POST 엔드 포인트 (http://localhost:3001/api/players)을 테스트 할 때

서버가 포함 된 JSON 객체로 응답 내가 원하는 데이터. 어떤 이유로 든 client.createPlayer은 서버에서 데이터를 반환하지 않습니다. 물론 그것은 그 문제의 일부일뿐입니다.이론적으로

, 내 client.createPlayer 결의 나는 방법은 바로, 내가 새로 만든 플레이어를 포함 할 데이터를 반환해야 client.createPlayer에 콜백으로 client.getPlayers를 호출하면?

그러나 그런 경우는 아닙니다.

내가 뭘 잘못하고 있니?

+0

이 'http : // localhost : 3001'은 의심스러워 보입니다 ... http : // localhost : 3001은 요청을하는 페이지가 다른 호스트가 아닌 곳에서로드되는 곳입니다. 'http : // localhost : 80' 또는 무엇인가 - 가져온 URL이''/ api/players '' 인 것을 볼 수 있습니다. 실제 코드입니다. 질문에 대해서 아무것도 삭제하지 않았고, "cross origin"요청인가요? –

+0

@ JaromandaX create-react-app를 사용하여 클라이언트 서버가 localhost : 3000에서 실행되고 express 서버가 localhost : 3001에서 실행됩니다. 클라이언트가 localhost : 3001에 대한 프록시 요청을 설정합니다. –

+0

ok - CORS 문제가 아닌지 확인합니다. –

답변

1

흥미롭게도, 내 App.jsx의 코드를 다음과 같이 변경하면 나는 결과를 얻을 수있었습니다. 그러나이 변경으로 인해 왜 효과가 있었는지 완전히 이해할 수 없으므로 정확한 답을 표시하지는 않습니다.

누군가가 차임하고 싶은데 왜 지금이 기능이 작동하는지 설명하고 싶다면 그 이유를 듣고 싶습니다.

App.jsx

// all other code omitted 

    client.createPlayer(playerData, (err) => { 
    console.error(err); 
    }, (data) => { 
    this.setState({ 
     highScores: [...this.state.highScores, ...data], 
    }); 
    });  

    client.getPlayers((data) => { 
    this.setState({ 
     inputScreen: false, // hide the input screen 
     highScoreScreen: true, // show the high score screen 
     yeti: yetiWin, 
     highScores: [...this.state.highScores, ...data], 
    }); 
    }, (err) => { 
    console.error(err); 
    }); 

// all other code omitted 

당신은 내가 더 이상 client.createPlayer에 성공 콜백으로 client.getPlayers를 호출하고 있습니다 없게됩니다 (고정). 그 위에 나는 client.createPlayer에서 반환 된 데이터를 사용하고 메서드 전에 client.createPlayer 메서드가 완료되지 않는 경우 폴백으로 상태에 추가합니다. 이렇게하면 setState이 다시 렌더링되면 새 플레이어가 표시됩니다.

관련 문제