ng-meumobi-utils was built to help make app development with meumobi faster and more efficient than ever before. It gives you simple AngularJS wrappers for the most popular Cordova and PhoneGap plugins available.
Download the installer for Node.js 6 or greater. Install [Gulp] to build dist.
$ npm i gulp@3 -g
+ gulp@3.9.1
% git clone https://github.com/meumobi/ng-meumobi-utils
% cd ng-meumobi-utils
% npm i
% gulp build
Tag and Push Release
$ git tag v0.0.9
$ git push origin v0.0.9
// Remember to increment version on package.json
The .then() handler catches the thrown exception and turns it into a rejected promise automatically.
http://stackoverflow.com/questions/33445415/javascript-promises-reject-vs-throw
https://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html
In Deferred anti-pattern, "deferred" objects are created for no reason, complicating code.
https://blog.domenic.me/the-revealing-constructor-pattern/ https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns#the-deferred-anti-pattern
function getUUID() {
return new Promise(function (resolve, reject) {
var cb_uuid = {
success: function(uuid) {
resolve(uuid);
},
fail: function() {
throw new Error('Unable to retrieve Device uuid');
}
};
var uniqueDeviceID = $window.plugins && $window.plugins.uniqueDeviceID;
if (uniqueDeviceID) {
uniqueDeviceID.get(cb_uuid.success, cb_uuid.fail);
} else {
throw new Error('Missing cordova-plugin-uniquedeviceid Plugin');
}
});
}
cordova-open use the extension of file to discover the mime-type. To maintain it we need to provide on App an up-to-date hash of mime-type/extension. It's why we should prefer to use fileOpener2 and use the mime-type provided by backend.
DeviceService.getDownloadDir(function(dir) {
fileTransfer.download(uri, dir + "/" + fileName, transfer.success, transfer.error, false);
});
var directory = null;
if (device.platform == "Android") {
directory = cordova.file.externalDataDirectory;
$log.debug("[Android] Set download dir: " + directory)
} else {
directory = cordova.file.dataDirectory;
$log.debug("[iOS] Set download dir: " + directory);
}
See $cordovaFileTransfer.download
https://www.raymondcamden.com/2014/11/19/Determing-installed-plugins-at-runtime-for-Cordova-and-PhoneGap-applications/: var md = cordova.require("cordova/plugin_list").metadata;
module ngMeumobi.Utils.api
.config(function (meuAPIProvider) {
meuAPIProvider.setOptions({
apiUrl: "http://meumobi.com/api/"
})
})
Promise.all: https://github.com/meumobi/IRmobi/issues/205
Measuring the mobile Experience
Add module 'ngMeumobi.Utils.analytics' as a dependency to your app unless you have already included one of its super-modules. On cordova add Plugin 'google-analytics-plugin' on config.xml.
On Bootstrap and after deviceready event fired init module:
deviceReady(function() {
...
meuAnalytics.startTrackerWithId(trackId);
...
}
On main controller
/*
Track current page
*/
$rootScope.$on('$routeChangeSuccess', function(e, current, prev) {
if (current.$$route)
deviceReady(function(){
meuAnalytics.trackView(current.$$route.title);
});
});
Event in Google Analytics is the user’s interaction /activity with a webpage element.
TrackEvent: meuAnalytics.trackEvent(Category, Action, Label, Value);
---- | ---- | ---- | ---- | Category | Action | Label | Value | |
---|---|---|---|---|---|---|---|---|
Events | Add to calendar | {Title} | - | |||||
Media | Open | {Title} | {Length} | |||||
Media | Download | {Title} | {Length} | |||||
Media | Play {media.type | name} | {Title} | {Duration} | ||||
Media | Delete | {Title} | {Length} | |||||
Social | Share {item.type | media} | {Title} | - | ||||
External Links | Click | {Title} | - | |||||
Authentication | Error | - | ||||||
Authentication | Forget Password | - | ||||||
Authentication | Login | - | ||||||
Authentication | Logout | - | ||||||
Account | Change Password | - | ||||||
Contact | Send | - | ||||||
Contact | Send | - | ||||||
Navigation | Swipe-left | {category.title} | - | |||||
Navigation | Swipe-right | {category.title} | - | |||||
Navigation | Scroll load | {category.title} | - | |||||
Navigation | Open SideBar-left | - | ||||||
Navigation | Open SideBar-right | - | ||||||
Navigation | Close SideBar-left | - | ||||||
Navigation | Close SideBar-right | - | ||||||
Social | Rate Android app | {value} | - | |||||
Social | Rate iOS app | {value} | - | |||||
Polls | Vote | {index} | - |
https://www.optimizesmart.com/complete-guide-cross-device-tracking-user-id-google-analytics/ https://developers.google.com/analytics/devguides/collection/analyticsjs/cookies-user-id
Add Service 'meuCalendar'
// if item.type == 'event' meuCalendar.createEventInteractively(item) .then( function(result) { / The Calendar App should emit msg to confirm Event creation / $log.debug("Success: " + JSON.stringify(result)); } ) .error( function(err) { UtilsService.toast(translateFilter("Error: " + angular.toJson(err))); } )
if start_date == end_date And are equal to 0 then the event is 'All day'.