@@ -8,8 +8,10 @@ import 'package:mixpanel_flutter/codec/mixpanel_message_codec.dart';
88
99/// The primary class for integrating Mixpanel with your app.
1010class Mixpanel {
11- static const MethodChannel _channel = const MethodChannel (
12- 'mixpanel_flutter' , StandardMethodCodec (MixpanelMessageCodec ()));
11+ static final MethodChannel _channel = kIsWeb
12+ ? const MethodChannel ('mixpanel_flutter' )
13+ : const MethodChannel (
14+ 'mixpanel_flutter' , StandardMethodCodec (MixpanelMessageCodec ()));
1315 static Map <String , String > _mixpanelProperties = {
1416 '\$ lib_version' : '2.4.3' ,
1517 'mp_lib' : 'flutter' ,
@@ -42,8 +44,8 @@ class Mixpanel {
4244 allProperties['optOutTrackingDefault' ] = optOutTrackingDefault;
4345 allProperties['trackAutomaticEvents' ] = trackAutomaticEvents;
4446 allProperties['mixpanelProperties' ] = _mixpanelProperties;
45- allProperties['superProperties' ] = superProperties;
46- allProperties['config' ] = config;
47+ allProperties['superProperties' ] = _MixpanelHelper . ensureSerializableProperties ( superProperties) ;
48+ allProperties['config' ] = _MixpanelHelper . ensureSerializableProperties ( config) ;
4749 await _channel.invokeMethod <void >('initialize' , allProperties);
4850 return Mixpanel (token);
4951 }
@@ -196,7 +198,7 @@ class Mixpanel {
196198 }) async {
197199 if (_MixpanelHelper .isValidString (eventName)) {
198200 await _channel.invokeMethod <void >('track' ,
199- < String , dynamic > {'eventName' : eventName, 'properties' : properties});
201+ < String , dynamic > {'eventName' : eventName, 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties) });
200202 } else {
201203 developer.log ('`track` failed: eventName cannot be blank' ,
202204 name: 'Mixpanel' );
@@ -229,8 +231,8 @@ class Mixpanel {
229231 if (_MixpanelHelper .isValidString (eventName)) {
230232 await _channel.invokeMethod <void >('trackWithGroups' , < String , dynamic > {
231233 'eventName' : eventName,
232- 'properties' : properties,
233- 'groups' : groups
234+ 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties) ,
235+ 'groups' : _MixpanelHelper . ensureSerializableProperties ( groups)
234236 });
235237 } else {
236238 developer.log ('`trackWithGroups` failed: eventName cannot be blank' ,
@@ -245,7 +247,7 @@ class Mixpanel {
245247 void setGroup (String groupKey, dynamic groupID) {
246248 if (_MixpanelHelper .isValidString (groupKey)) {
247249 _channel.invokeMethod <void >('setGroup' ,
248- < String , dynamic > {'groupKey' : groupKey, 'groupID' : groupID});
250+ < String , dynamic > {'groupKey' : groupKey, 'groupID' : _MixpanelHelper . ensureSerializableValue ( groupID) });
249251 } else {
250252 developer.log ('`setGroup` failed: groupKey cannot be blank' ,
251253 name: 'Mixpanel' );
@@ -260,7 +262,7 @@ class Mixpanel {
260262 /// return an instance of MixpanelGroup that you can use to update
261263 /// records in Mixpanel Group Analytics
262264 MixpanelGroup getGroup (String groupKey, dynamic groupID) {
263- return new MixpanelGroup (this ._token, groupKey, groupID);
265+ return new MixpanelGroup (this ._token, groupKey, _MixpanelHelper . ensureSerializableValue ( groupID) );
264266 }
265267
266268 /// Add a group to this user's membership for a particular group key
@@ -270,7 +272,7 @@ class Mixpanel {
270272 void addGroup (String groupKey, dynamic groupID) {
271273 if (_MixpanelHelper .isValidString (groupKey)) {
272274 _channel.invokeMethod <void >('addGroup' ,
273- < String , dynamic > {'groupKey' : groupKey, 'groupID' : groupID});
275+ < String , dynamic > {'groupKey' : groupKey, 'groupID' : _MixpanelHelper . ensureSerializableValue ( groupID) });
274276 } else {
275277 developer.log ('`addGroup` failed: groupKey cannot be blank' ,
276278 name: 'Mixpanel' );
@@ -284,7 +286,7 @@ class Mixpanel {
284286 void removeGroup (String groupKey, dynamic groupID) {
285287 if (_MixpanelHelper .isValidString (groupKey)) {
286288 _channel.invokeMethod <void >('removeGroup' ,
287- < String , dynamic > {'groupKey' : groupKey, 'groupID' : groupID});
289+ < String , dynamic > {'groupKey' : groupKey, 'groupID' : _MixpanelHelper . ensureSerializableValue ( groupID) });
288290 } else {
289291 developer.log ('`removeGroup` failed: groupKey cannot be blank' ,
290292 name: 'Mixpanel' );
@@ -301,7 +303,7 @@ class Mixpanel {
301303 void deleteGroup (String groupKey, dynamic groupID) {
302304 if (_MixpanelHelper .isValidString (groupKey)) {
303305 _channel.invokeMethod <void >('deleteGroup' ,
304- < String , dynamic > {'groupKey' : groupKey, 'groupID' : groupID});
306+ < String , dynamic > {'groupKey' : groupKey, 'groupID' : _MixpanelHelper . ensureSerializableValue ( groupID) });
305307 } else {
306308 developer.log ('`deleteGroup` failed: groupKey cannot be blank' ,
307309 name: 'Mixpanel' );
@@ -323,7 +325,7 @@ class Mixpanel {
323325 /// * [properties] A Map containing super properties to register
324326 Future <void > registerSuperProperties (Map <String , dynamic > properties) async {
325327 await _channel.invokeMethod <void >(
326- 'registerSuperProperties' , < String , dynamic > {'properties' : properties});
328+ 'registerSuperProperties' , < String , dynamic > {'properties' : _MixpanelHelper . ensureSerializableProperties ( properties) });
327329 }
328330
329331 /// Register super properties for events, only if no other super property with the
@@ -336,7 +338,7 @@ class Mixpanel {
336338 Map <String , dynamic > properties,
337339 ) async {
338340 await _channel.invokeMethod <void >('registerSuperPropertiesOnce' ,
339- < String , dynamic > {'properties' : properties});
341+ < String , dynamic > {'properties' : _MixpanelHelper . ensureSerializableProperties ( properties) });
340342 }
341343
342344 /// Remove a single superProperty, so that it will not be sent with future calls to track().
@@ -450,7 +452,10 @@ class Mixpanel {
450452/// persist across stops and starts of your application, until you make another
451453/// call to identify using a different id.
452454class People {
453- static const MethodChannel _channel = const MethodChannel ('mixpanel_flutter' );
455+ static final MethodChannel _channel = kIsWeb
456+ ? const MethodChannel ('mixpanel_flutter' )
457+ : const MethodChannel (
458+ 'mixpanel_flutter' , StandardMethodCodec (MixpanelMessageCodec ()));
454459
455460 final String _token;
456461
@@ -467,7 +472,7 @@ class People {
467472 if (_MixpanelHelper .isValidString (prop)) {
468473 Map <String , dynamic > properties = {prop: to};
469474 _channel.invokeMethod <void >('set' ,
470- < String , dynamic > {'token' : this ._token, 'properties' : properties});
475+ < String , dynamic > {'token' : this ._token, 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties) });
471476 } else {
472477 developer.log ('`people set` failed: prop cannot be blank' ,
473478 name: 'Mixpanel' );
@@ -482,7 +487,7 @@ class People {
482487 if (_MixpanelHelper .isValidString (prop)) {
483488 Map <String , dynamic > properties = {prop: to};
484489 _channel.invokeMethod <void >('setOnce' ,
485- < String , dynamic > {'token' : this ._token, 'properties' : properties});
490+ < String , dynamic > {'token' : this ._token, 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties) });
486491 } else {
487492 developer.log ('`people setOnce` failed: prop cannot be blank' ,
488493 name: 'Mixpanel' );
@@ -499,7 +504,7 @@ class People {
499504 Map <String , dynamic > properties = {prop: by};
500505 if (_MixpanelHelper .isValidString (prop)) {
501506 _channel.invokeMethod <void >('increment' ,
502- < String , dynamic > {'token' : this ._token, 'properties' : properties});
507+ < String , dynamic > {'token' : this ._token, 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties) });
503508 } else {
504509 developer.log ('`people increment` failed: prop cannot be blank' ,
505510 name: 'Mixpanel' );
@@ -516,12 +521,12 @@ class People {
516521 if (kIsWeb || Platform .isIOS) {
517522 Map <String , dynamic > properties = {name: value};
518523 _channel.invokeMethod <void >('append' ,
519- < String , dynamic > {'token' : this ._token, 'properties' : properties});
524+ < String , dynamic > {'token' : this ._token, 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties) });
520525 } else {
521526 _channel.invokeMethod <void >('append' , < String , dynamic > {
522527 'token' : this ._token,
523528 'name' : name,
524- 'value' : value
529+ 'value' : _MixpanelHelper . ensureSerializableValue ( value)
525530 });
526531 }
527532 } else {
@@ -541,12 +546,12 @@ class People {
541546 if (kIsWeb || Platform .isIOS) {
542547 Map <String , dynamic > properties = {name: value};
543548 _channel.invokeMethod <void >('union' ,
544- < String , dynamic > {'token' : this ._token, 'properties' : properties});
549+ < String , dynamic > {'token' : this ._token, 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties) });
545550 } else {
546551 _channel.invokeMethod <void >('union' , < String , dynamic > {
547552 'token' : this ._token,
548553 'name' : name,
549- 'value' : value
554+ 'value' : _MixpanelHelper . ensureSerializableValue ( value)
550555 });
551556 }
552557 } else {
@@ -566,12 +571,12 @@ class People {
566571 if (kIsWeb || Platform .isIOS) {
567572 Map <String , dynamic > properties = {name: value};
568573 _channel.invokeMethod <void >('remove' ,
569- < String , dynamic > {'token' : this ._token, 'properties' : properties});
574+ < String , dynamic > {'token' : this ._token, 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties) });
570575 } else {
571576 _channel.invokeMethod <void >('remove' , < String , dynamic > {
572577 'token' : this ._token,
573578 'name' : name,
574- 'value' : value
579+ 'value' : _MixpanelHelper . ensureSerializableValue ( value)
575580 });
576581 }
577582 } else {
@@ -603,7 +608,7 @@ class People {
603608 _channel.invokeMethod <void >('trackCharge' , < String , dynamic > {
604609 'token' : this ._token,
605610 'amount' : amount,
606- 'properties' : properties
611+ 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties)
607612 });
608613 } else {
609614 developer.log ('`people trackCharge` failed: amount cannot be blank' ,
@@ -631,7 +636,10 @@ class People {
631636///
632637/// The MixpanelGroup object is used to update properties in a group's Group Analytics record.
633638class MixpanelGroup {
634- static const MethodChannel _channel = const MethodChannel ('mixpanel_flutter' );
639+ static final MethodChannel _channel = kIsWeb
640+ ? const MethodChannel ('mixpanel_flutter' )
641+ : const MethodChannel (
642+ 'mixpanel_flutter' , StandardMethodCodec (MixpanelMessageCodec ()));
635643
636644 final String _token;
637645 final String _groupKey;
@@ -656,7 +664,7 @@ class MixpanelGroup {
656664 'token' : this ._token,
657665 'groupKey' : this ._groupKey,
658666 'groupID' : this ._groupID,
659- 'properties' : properties
667+ 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties)
660668 });
661669 } else {
662670 developer.log ('`group set` failed: prop cannot be blank' ,
@@ -676,7 +684,7 @@ class MixpanelGroup {
676684 'token' : this ._token,
677685 'groupKey' : this ._groupKey,
678686 'groupID' : this ._groupID,
679- 'properties' : properties
687+ 'properties' : _MixpanelHelper . ensureSerializableProperties ( properties)
680688 });
681689 } else {
682690 developer.log ('`group setOnce` failed: prop cannot be blank' ,
@@ -714,7 +722,7 @@ class MixpanelGroup {
714722 'groupKey' : this ._groupKey,
715723 'groupID' : this ._groupID,
716724 'name' : name,
717- 'value' : value
725+ 'value' : _MixpanelHelper . ensureSerializableValue ( value)
718726 });
719727 } else {
720728 developer.log ('`group remove` failed: name cannot be blank' ,
@@ -745,7 +753,7 @@ class MixpanelGroup {
745753 'groupKey' : this ._groupKey,
746754 'groupID' : this ._groupID,
747755 'name' : name,
748- 'value' : value
756+ 'value' : _MixpanelHelper . ensureSerializableValue ( value)
749757 });
750758 }
751759}
@@ -755,4 +763,32 @@ class _MixpanelHelper {
755763 // ignore: unnecessary_null_comparison
756764 return input != null && input.isNotEmpty;
757765 }
766+
767+ /// Converts complex types to basic types for web platform
768+ static dynamic ensureSerializableValue (dynamic value) {
769+ if (! kIsWeb) {
770+ return value;
771+ }
772+ if (value == null ) {
773+ return null ;
774+ } else if (value is DateTime ) {
775+ return value.toIso8601String ();
776+ } else if (value is Uri ) {
777+ return value.toString ();
778+ } else if (value is Map ) {
779+ return value.map ((k, v) => MapEntry (k, ensureSerializableValue (v)));
780+ } else if (value is List ) {
781+ return value.map ((v) => ensureSerializableValue (v)).toList ();
782+ } else {
783+ return value;
784+ }
785+ }
786+
787+ /// Converts properties map for web platform
788+ static Map <String , dynamic >? ensureSerializableProperties (Map <String , dynamic >? properties) {
789+ if (! kIsWeb || properties == null ) {
790+ return properties;
791+ }
792+ return properties.map ((k, v) => MapEntry (k, ensureSerializableValue (v)));
793+ }
758794}
0 commit comments