[Flu] 서버 API SELECT에서 여러행 DATA 받을 때 > Flutter/Dart/Node

본문 바로가기
사이트 내 전체검색

Flutter/Dart/Node

[Flu] 서버 API SELECT에서 여러행 DATA 받을 때

페이지 정보

작성자 sbLAB 댓글 0건 조회 1,989회 작성일 22-12-10 23:05

본문

DART <-> PHP


//Member data class
class MemberModel {
  int id;
  String email;
  String pw;
  String ip;
  String datetimeadd;

  MemberModel(
      { required this.id,
        required this.email,
        required this.pw,
        required this.ip,
        required this.datetimeadd});

  factory MemberModel.fromJson(Map<String, dynamic> json) {
    return MemberModel(
      id: json['id'],
      email: json['email'],
      pw: json['pw'],
      ip: json['ip'],
      datetimeadd: json['datetimeadd'],
    );
  }
}
 


[기존 php 웹서버에서 질의결과 Row 데이타가 없을때 {}  또는 nodata 문자열이 리턴 되는 조건을 가정] 

 서버 API SELECT에서 리스트데이타 받을 때

 1) 여러행이 List(memberModer) 형태로 수신되는 경우 

  질의데이타가 리턴된다는 전제로 

return (json.decode(response.body) as List).map((i) =>MemberModel.fromJson(i)).toList(); 

또는 같은형태의

 var jsonResponse = json.decode(response.body) as List<dynamic>;
return jsonResponse
.map<MemberModel>((data) => MemberModel.fromJson(data))
.toList();

 이렇게 받을수도 있을것 같으나,


 2) 해당되는 자료가 없을때 서버API에서 {} 또는 nodate 문자열이 리턴되는 경우라면 위 방법 불가

  {}은 문자열로 List가 아님에도 강제 캐스팅(as List) 되고 있음 -> '자료없음' 체크도 불가능하고 오류 유발


[php 웹서버에서 데이타가 없을때 {}  또는 nodata 문자열이 리턴 되는 조건을 가정] 

        header('Content-Type: application/json; charset=UTF-8');
        $json = json_encode('{}', JSON_PRETTY_PRINT); //{} 문자열 리턴 -.-
        echo $json;


※ 보통(정상)의 경우는 웹서버에서 비어있는 []  <- array를 리턴하면 됨.

        header('Content-Type: application/json; charset=UTF-8');
        $json = json_encode([], JSON_PRETTY_PRINT); //빈 JSON 리턴
        echo $json;



3) 해결(list 인지 문자열 인지 판단) 

단 1개행이라도 수신이되면 List 타입이고, 해당 행이 없어 {} 공백이 수신되면 문자열 타입임.

List 타입이면 List add 해서 전체행 다음로직에 리턴, {}공백이면 List add 없이 List<MemberModel> memberList = [];  리턴

즉, List<MemberModel> 자료형 변형 없이 다음 로직에 전달.


[질의 데이타  리턴 된 경우] 

dfa67cd43db99f38e7f7d98bce5b5367_1670682576_7526.jpg
 

[ {}  리턴 된 경우] 

dfa67cd43db99f38e7f7d98bce5b5367_1670682586_2477.jpg
 

Dart Type 확인 예제

  main() {
    var parsed = "nodate";

    if (parsed is List) {
      print("parsed is List!!");
    } else {
      print("parsed is String!");
    }
    //parsed is String!

    var parsed2 = [1, 2, 3];
    if (parsed2 is List<dynamic>) {
      print("parsed is List!!");
    } else {
      print("parsed is String!");
    }
    //parsed is List!!
  }
 

 

▼ 위와 같이 Type 확인 적용

   
    List<MemberModel> memberList = [];
    ....
    ....

    if (response.statusCode == 200) {    //서버요청 성공:200

      var parsed = json.decode(response.body);
      if (parsed is List<dynamic>) {
        for (var member in parsed) {
          memberList.add(MemberModel.fromJson(member));
        }
      }
      return memberList;

 



[웹에서 JSON 문자열 -> DATA로 받기]



class FutureFetchService {
  Future<List<MemberModel>> fetchMember() async {
    List<MemberModel> memberList = [];
    var url = Uri.parse('http://10.0.2.2/jp/memberselect.php');

    Map formdata = {
      'email': 'love2@daum.net',
      'pw': '12345',
      'token': 'eyJhbGciOiJI....5.aWwuY29t....d300fa99660e763056e54dd'
    };
    var body = json.encode(formdata);
    var response = await http.post(url,
        headers: {"Content-Type": "application/json"}, body: body);

    if (response.statusCode == 200) {    //서버요청 성공:200

      var parsed = json.decode(response.body);
      if (parsed is List<dynamic>) {
        for (var member in parsed) {
          memberList.add(MemberModel.fromJson(member));
        }
      }
      return memberList;

      //return (json.decode(response.body) as List).map((i) =>MemberModel.fromJson(i)).toList();

    } else {
      //Exception
      throw Exception('Failed to load');
    }
  }
}

 


 
//_ListViewPageState
class _ListViewPageState extends State<ListViewPage> {
  late Future<List<MemberModel>> _members;

  @override
  void initState() {
    super.initState();
    _members = FutureFetchService().fetchMember();
  }
  ...
 



[일반적인 보통(정상)의 조건일 경우]

웹서버(php)에서 200(정상처리) 상태값과 함께 List json 리턴(질의결과가 없을 경우 빈array 인 [] 리턴함)

              $result = $stmt->fetchAll(PDO::FETCH_OBJ);    //질의결과가 없으면 array(0)           
$response->getBody()->write(json_encode($result));
                return $response
                    ->withHeader('content-type', 'application/json')
                    ->withStatus(200);


플러터(Dart)에서 200(정상처리) 응답을 받으면, List  질의결과가 있든지 없든지 상관없이 받음.

class FutureFetchService {
Future<List<MemberModel>> fetchMember() async {
final queryParameters = {
'email': '11@daum.net',
'pw': '11111',
'tk': '111111....dX9Hs'
};
var url = Uri.http('localhost', '/restapi/public/s/100', queryParameters);
var response = await http.get(url);

if (response.statusCode == 200) {
var jsonResponse = json.decode(response.body) as List<dynamic>;
return jsonResponse
.map<MemberModel>((data) => MemberModel.fromJson(data))
.toList();

} else {
throw Exception('Failed to load');
}
}
}



[다른이야기]


//Member data class 

  int id;
  String email;
  String pw;
  String ip;
  String datetimeadd;


을 아래 처럼 final 로 선언하게 되면...

  final int id;
  final String email;
  final String pw;
  final String ip;
  final String datetimeadd;



서버에서 받아온 데이타를 플래터 FutureBuilder(..) 에서 snapshot 으로 받아와 ListView.builder(...) 에 적용 한 후


    return FutureBuilder(
        future: _members,
        builder: (context, AsyncSnapshot<List<MemberModel>> snapshot) {



아래 snapshot.data![index].email = "change"; 처럼 텍스트 변경할 때 이미 초기화(initialized) 되어 있다고 나오며 변경이 불가해짐.

                    child: GestureDetector(
                                onTap: () {
                                  setState(() {
                                    //snapshot.data?.removeAt(index);
                                    snapshot.data![index].email = "change";
                                  });
                                }, // Image tapped
                                child: Image.asset(imageList[index]),
                              )



댓글목록

등록된 댓글이 없습니다.

회원로그인

접속자집계

오늘
265
어제
417
최대
1,279
전체
221,036

그누보드5
Copyright © sebom.com All rights reserved.