onSuccess<R> method

FutureOr<R?> onSuccess<R>(
  1. DataResponse response,
  2. DataRequestLabel label
)
inherited

Implementation

FutureOr<R?> onSuccess<R>(
    DataResponse response, DataRequestLabel label) async {
  // remove all operations with this label
  OfflineOperation.remove(label, this as RemoteAdapter);

  final body = response.body;

  // this will happen when `returnBytes` is requested
  if (body is Uint8List) {
    return response as R;
  }

  if (label.kind == 'save') {
    if (label.model == null) {
      return null;
    }
    if (body == null) {
      // return original model if response was empty
      return label.model as R?;
    }

    // deserialize already inits models
    // if model had a key already, reuse it
    final deserialized = await deserialize(body as Map<String, dynamic>);
    final model = deserialized.model!.withKeyOf(label.model as T);

    model.saveLocal();
    log(label, 'saved in local storage and remote');

    return model as R?;
  }

  if (label.kind == 'delete') {
    log(label, 'deleted in local storage and remote');
    return null;
  }

  final isFindAll = label.kind.startsWith('findAll');
  final isFindOne = label.kind.startsWith('findOne');
  final isCustom = label.kind == 'custom';

  final adapter = this as RemoteAdapter;

  // custom non-JSON request, return as-is
  if (isCustom &&
      !(response.headers['content-type']?.contains('json') ?? false)) {
    return response.body as R?;
  }

  final deserialized = await deserialize(body);

  if (isFindAll || (isCustom && deserialized.model == null)) {
    for (final model in [...deserialized.models, ...deserialized.included]) {
      model._remoteAdapter.localAdapter.save(model._key!, model);
    }
    deserialized._log(adapter, label);

    late R? models;
    if (response.statusCode == 304) {
      models = await adapter.findAll(remote: false) as R?;
    } else {
      models = deserialized.models as R?;
    }

    return models;
  }

  if (isFindOne || (isCustom && deserialized.model != null)) {
    for (final model in [...deserialized.models, ...deserialized.included]) {
      model._remoteAdapter.localAdapter.save(model._key!, model);
    }
    deserialized._log(adapter, label);

    late R? model;
    if (response.statusCode == 304) {
      model = await adapter.findOne(label.id!, remote: false) as R?;
    } else {
      model = deserialized.model as R?;
    }

    return model;
  }

  return null;
}