Home > OS >  Issues with fetching urls from api flutter
Issues with fetching urls from api flutter

Time:11-01

working on a flutter project for a while now, didn't notice it at all.

I'm fetching events as objects from an API, one of the variables that the events have is a URL, which for some reason is the only variable that gets fetched as 'Null' and not the real variables value (apis response in postman and etc are fine and there are real URLs).

api_calls.dart: Notice I've purposely deleted the API url and the token

class GetCandEventsByEntityId {
  static Future<ApiCallResponse> call({
    int? entityId,
    String? rakazCode,
    String? search,
  }) {
    final body = '''
{
  "token": "",
  "entityId": ${entityId},
  "rakazCode": ${rakazCode},
  "pageNumber": 1,
  "rowsPerPage": 300,
  "search": "${search}",
}''';

    return ApiManager.instance.makeApiCall(
      callName: 'GetCandEventsByEntityId',
      apiUrl:
      '',
      callType: ApiCallType.POST,
      headers: {},
      params: {
        'entityId': entityId,
        'rakazCode': rakazCode,
        'search': search,
      },
      body: body,
      bodyType: BodyType.JSON,
      returnBody: true,
    );
  }
  static dynamic rakazUrl(dynamic response) => getJsonField(response,
    r'''$..url''',);
static dynamic descEvent(dynamic response) => getJsonField(
    response,
    r'''$..eventDescription''',
  );
  static dynamic statusEvent(dynamic response) => getJsonField(
    response,
    r'''$..status_event''',
  );
  static dynamic dateEvent(dynamic response) => getJsonField(
    response,
    r'''$..date_event''',
  );
  static dynamic resultEvent(dynamic response) => getJsonField(
    response,
    r'''$..event_result_code''',
  );
  static dynamic rakazPhone(dynamic response) => getJsonField(response,
    r'''$..rakazPhone''',);
  static dynamic rakazName(dynamic response) => getJsonField(response,
    r'''$..rakazName''',);
  static dynamic eventRemark(dynamic response) => getJsonField(response, r'''$..eventRemark''',);
  static dynamic eventNum(dynamic response) => getJsonField(response, r'''$..eventno''',);
}

worker_activity_widget.dart: Hiding most of the irrelevant lines to give a focus on the 'probably causing the problem' lines

import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:.../index.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../backend/api_requests/api_calls.dart';
import '../components/worker_container_widget.dart';
import '../constants.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../skeleton.dart';

class WorkerActivityWidget extends StatefulWidget {
  const WorkerActivityWidget({
    Key? key,
    this.firstName,
    this.lastName,
    this.phoneNumber,
    this.myUrl,
    this.search,
    this.entityId,
  }) : super(key: key);

  final String? firstName;
  final String? lastName;
  final String? phoneNumber;
  final String? myUrl;
  final int? entityId;
  final String? search; 
  @override
  _WorkerActivityWidgetState createState() => _WorkerActivityWidgetState();
}

class eventModel {
  final String dateEvent;
  final String statusEvent;
  final String descEvent;
  final String rakazUrl;
  final String rakazPhone;
  final String rakazName;

  const eventModel({
    required this.dateEvent,
    required this.statusEvent,
    required this.descEvent,
    required this.rakazName,
    required this.rakazUrl,
    required this.rakazPhone,
  });

  static eventModel fromJson(Map<String, dynamic> json) {

    return eventModel(
      dateEvent: json['date_event'],
      statusEvent: json['status_event'],
      descEvent: json['eventDescription'],
      rakazName: json['rakazName'].toString(),
      rakazUrl: json['url'].toString(),
      rakazPhone: json['rakazPhone'].toString(), 
    );
  }
}

class _WorkerActivityWidgetState extends State<WorkerActivityWidget> {
  final scaffoldKey = GlobalKey<ScaffoldState>();
  List<bool> isSelected = [true, false];
  List<eventModel> filteredEvents = [];
  bool start = true;
  DateTime now = new DateTime.now();
@override
  Widget build(BuildContext context) {
    var temprakaz = 0;
    return FutureBuilder<ApiCallResponse>(
        future: GetCandEventsByEntityId.call(
          entityId: widget.entityId,
          rakazCode: temprakaz.toString(),
          search: widget.search,
        ),
        builder: (context, snapshot) { ... }
          final listViewGetCandEventsByEntityIdResponse = snapshot.data!;
          final data = listViewGetCandEventsByEntityIdResponse
              .jsonBody['eventList'] as List;
          List<eventModel> events =
              data.map((e) => eventModel.fromJson(e)).toList();
  

without the toString() in return eventModel( rakazUrl: json['url'],); This would be the outcome:

The relevant error-causing widget was: FutureBuilder FutureBuilder: /lib/worker_pages/worker_activity_widget.dart:88:12

return FutureBuilder<ApiCallResponse>(
        future: GetCandEventsByEntityId.call(
          entityId: widget.entityId,
          rakazCode: temprakaz.toString(),
          search: widget.search,
        ),

When the exception was thrown, this was the stack: #0 eventModel.fromJson (worker_pages/worker_activity_widget.dart:60:21)

rakazUrl: json['url'],

#1 _WorkerActivityWidgetState.build.. (package:/worker_pages/worker_activity_widget.dart:184:42)

final listViewGetCandEventsByEntityIdResponse = snapshot.data!;
          final data = listViewGetCandEventsByEntityIdResponse
              .jsonBody['eventList'] as List;
          List<eventModel> events =
              data.map((e) => eventModel.fromJson(e)).toList();

CodePudding user response:

First of all, the code is quite messy so separated each class to a different page - Making it way more understandable and clear Seems like there issue was around the search string. its Value was in a different language (Which was fine when testing out the API call in postman) but something in flutter made the URL get fetched as null for some reason.

Decided to remove the search string and just to filter out the list of objects when all of the objects already got fetched. And displayed only the filtered objects to the user. Not an ideal solution but better than nothing

  • Related