Search code examples
flutterdartspecial-characters

How to translate special characters in a string in a Flutter application? Example: "Déjà Vu" to "Déjà Vu"


I am new to Flutter development and I am trying to decode or translate special characters. The example I am working with looks like this presented as normal text in flutter:

Example: "Déjà Vu" to "Déjà Vu"

The left is how it appears on the UI and the result I would like to see is on the right.

I have tried using Runes class via docs --> https://api.dart.dev/stable/1.24.3/dart-core/Runes-class.html but no luck.

This is the non-working code:

child: Text(new Runes("Déjà Vu").string)

Update:I tried to pass 'Content-type': 'application/json; charset=utf-8', in the API call, however it didn't seem to correct this particular issue. I will attach a snapshot of the response (I ran it with the new headers and also withoutenter image description here)

Here is the code:

   Future<http.Response> _attemptCall(String suffix) => http.get(
        '$kBaseURL$suffix',
        headers: {
          'Authorization': 'Bearer $_accessToken',
          'Content-type': 'application/json; charset=utf-8',
        },
      );

  Future<T> _authorizedCall<T>(
    String suffix,
    T Function(String) decode,
  ) async {
    if (_accessToken == '') {
      await refreshToken();
    }
    http.Response response = await _attemptCall(suffix);

    var resBody = response.body;
    print('This is the response --> $resBody');
    if (response.statusCode == 401) {
      await refreshToken();
      response = await _attemptCall(suffix);
    }

    if (response.statusCode == 200) {
      return decode(response.body);
    }
    return null;
  }

  @override
  Future<Episode> getEpisodeDetails(String id) => _authorizedCall(
        _episodeDetailUrl(id),
        (s) => Episode.fromJson(jsonDecode(s)),
      );

Solution

  • This charset mangling is called Mojibake (Thanks Randal Schwartz for pointing out!)

    You cannot change "Déjà Vu" back to "Déjà Vu", you have to take action on either the way data is encoded and sent or the way you decode the response.

    See the binary representation of these utf-8 characters:

    11000011 10000011 Ã   --> there is no way to tell `Ã` that it should be `à`
    11000010 10101001 ©
    
    11000011 10100000 à
    11000011 10101001 é
    

    You need to fix the problem upstream with the either the API response:

    Content-type: application/json; charset=utf-8
    

    The API is sending you back a stream of bytes, and should be utf8 in order to avoid this kind of output.

    Or the way you decode the stream of bytes, you may also change:

    return decode(response.body)
    

    To

    return decode(utf8.decode(response.bodyBytes));