deep_pick 0.4.0

  • Readme
  • Changelog
  • Example
  • Installing
  • 92

deep_pick #

Pub

A library to access deep nested values inside of dart data structures, like returned from dynamic jsonDecode(String source).

Example #

import 'dart:convert';

import 'package:deep_pick/deep_pick.dart';

void main() {
  final json = jsonDecode('''
{
  "shoes": [
     { 
       "id": "421",
       "name": "Nike Zoom Fly 3",
       "tags": ["cool", "new"]
     }
  ]
}
''');

  final name = pick(json, 'shoes', 0, 'name').asString();
  print(name); // Nike Zoom Fly 3

  final manufacturer = pick(json, 'shoes', 0, 'manufacturer').asStringOrNull();
  print(manufacturer); // null

  final id = pick(json, 'shoes', 0, 'id').asInt();
  print(id); // 421

  final tags = pick(json, 'shoes', 0, 'tags').asListOrEmpty<String>();
  print(tags); // [cool, new]
}

License #

Copyright 2019 Pascal Welsch

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

0.4.0 #

Map objects #

New APIs to map picks to objects and to map list elements to obejcts.

RequiredPick.let<R>(R Function(RequiredPick pick) block): R
Pick.letOrNull<R>(R Function(RequiredPick pick) block): R

RequiredPick.asList<T>([T Function(Pick) map]): List<T> 
Pick.asListOrNull<T>([T Function(Pick) map]): List<T> 
Pick.asListOrEmpty<T>([T Function(Pick) map]): List<T> 

Here are two example how to actually use them.

// easily pick and map objects to dart objects
final Shoe oneShoe = pick(json, 'shoes', 0).letOrNull((p) => Shoe.fromPick(p));

// map list of picks to dart objects
final List<Shoe> shoes = 
     pick(json, 'shoes').asListOrEmpty((p) => Shoe.fromPick(p.required()));

Required picks #

Pick now offers a new required() method returning a RequiredPick. It makes sure the picked value exists or crashes if it is null. Because it can't be null, RequiredPick doesn't offer fallback methods like .asIntOrNull() but only .asInt(). This makes the API a bit easier to use for values you can't live without.

// use required() to crash if a object doesn't exist
final name = pick(json, 'shoes', 0, 'name').required().asString();
print(name); // Nike Zoom Fly 3

Note: Calling .asString() directly on Pick has been deprecated. You now have to call required() first to convert the Pick to a RequiredPick or use a mapping method with fallbacks.

Pick deeper #

Ever got a Pick/RequiredPick and you wanted to pick even further. This is now possible with the call method. Very useful in constructors when parsing methods.

  factory Shoe.fromPick(RequiredPick pick) {
    return Shoe(
      id: pick('id').required().asString(),
      name: pick('name').required().asString(),
      manufacturer: pick('manufacturer').asStringOrNull(),
      tags: pick('tags').asListOrEmpty(),
    );
  }

Bugfixes #

  • Don't crash when selecting a out of range index from a List
  • .asMap(), .asMapOrNull() and .asMapOrEmpty() now consistently return Map<dynamic, dynamic> (was Map<String, dynamic>)

Also the lib has been converted to use static extension methods which were introduced in Dart 2.6

0.3.0 #

asMap now expects the key type, defaults to dynamic instead of String

-Pick.asMap(): Map<String, dynamic>
+Pick.asMap<T>(): Map<T, dynamic>

0.2.0 #

New API! The old parse* methods are now deprecated, but still work. Replace them with the new pick(json, arg0-9...) method.

- final name = parseJsonToString(json, 'shoes', 0, 'name');
+ final name = pick(json, 'shoes', 0, 'name').asString();

pick returns a Pick which offers a rich API to parse values.

.asString()
.asStringOrNull()
.asMap()
.asMapOrEmpty()
.asMapOrNull()
.asList()
.asListOrEmpty()
.asListOrNull()
.asBool()
.asBoolOrNull()
.asBoolOrTrue()
.asBoolOrFalse()
.asInt()
.asIntOrNull()
.asDouble()
.asDoubleOrNull()
.asDateTime()
.asDateTimeOrNull()

0.1.1 #

  • pubspec description updated

0.1.0 #

  • Initial version

example/deep_pick_example.dart

// ignore_for_file: avoid_print, always_require_non_null_named_parameters
import 'dart:convert';

import 'package:deep_pick/deep_pick.dart';

void main() {
  final json = jsonDecode('''
{
  "shoes": [
     { 
       "id": "421",
       "name": "Nike Zoom Fly 3",
       "tags": ["nike", "JustDoIt"]
     },
     { 
       "id": "532",
       "name": "adidas Ultraboost",
       "manufacturer": "adidas",
       "tags": ["adidas", "ImpossibleIsNothing"]
     }
  ]
}
''');
  // pick a value deep down the json structure
  final firstTag = pick(json, 'shoes', 1, 'tags', 0).asStringOrNull();
  print(firstTag); // adidas

  // fallback to null if it couldn't be found
  final manufacturer = pick(json, 'shoes', 0, 'manufacturer').asStringOrNull();
  print(manufacturer); // null

  // use required() to crash if a object doesn't exist
  final name = pick(json, 'shoes', 0, 'name').required().asString();
  print(name); // Nike Zoom Fly 3

  // you decide which type you want
  final id = pick(json, 'shoes', 0, 'id');
  print(id.asIntOrNull()); // 421
  print(id.asDoubleOrNull()); // 421.0
  print(id.asStringOrNull()); // "421"

  // pick lists
  final tags = pick(json, 'shoes', 0, 'tags').asListOrEmpty<String>();
  print(tags); // [nike, JustDoIt]

  // pick maps
  final shoe = pick(json, 'shoes', 0).required().asMap();
  print(shoe); // {id: 421, name: Nike Zoom Fly 3, tags: [nike, JustDoIt]}

  // easily pick and map objects to dart objects
  final firstShoe = pick(json, 'shoes', 0).letOrNull((p) => Shoe.fromPick(p));
  print(firstShoe);
  // Shoe{id: 421, name: Nike Zoom Fly 3, tags: [nike, JustDoIt]}

  // falls back to null when the value couldn't be picked
  final thirdShoe = pick(json, 'shoes', 2).letOrNull((p) => Shoe.fromPick(p));
  print(thirdShoe); // null

  // map list of picks to dart objects
  final shoes =
      pick(json, 'shoes').asListOrEmpty((p) => Shoe.fromPick(p.required()));
  print(shoes);
  // [
  //   Shoe{id: 421, name: Nike Zoom Fly 3, tags: [nike, JustDoIt]},
  //   Shoe{id: 532, name: adidas Ultraboost, tags: [adidas, ImpossibleIsNothing]}
  // ]
}

/// A data class representing a shoe model
///
/// PODO - plain old dart object
class Shoe {
  const Shoe({
    this.id,
    this.name,
    this.manufacturer,
    this.tags,
  })  : assert(id != null),
        assert(name != null),
        assert(tags != null);

  factory Shoe.fromPick(RequiredPick pick) {
    return Shoe(
      id: pick('id').required().asString(),
      name: pick('name').required().asString(),
      manufacturer: pick('manufacturer').asStringOrNull(),
      tags: pick('tags').asListOrEmpty(),
    );
  }

  /// never null
  final String id;

  /// never null
  final String name;

  /// optional
  final String /*?*/ manufacturer;

  /// never null, falls back to empty list
  final List<String> tags;

  @override
  String toString() {
    return 'Shoe{id: $id, name: $name, tags: $tags}';
  }

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is Shoe &&
          runtimeType == other.runtimeType &&
          id == other.id &&
          name == other.name &&
          tags == other.tags;

  @override
  int get hashCode => id.hashCode ^ name.hashCode ^ tags.hashCode;
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  deep_pick: ^0.4.0

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter pub get

Alternatively, your editor might support pub get or flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:deep_pick/deep_pick.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
85
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
92
Learn more about scoring.

We analyzed this package on Jan 27, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.1
  • pana: 0.13.4

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.6.0 <3.0.0
Dev dependencies
lint ^0.2.0
test ^1.6.0