Reload angular-translate-static-loader-files within app, without refresh in Ionic - angularjs

I'm working on this Ionic app and I'm using angular-translate-loader-static-files with angular-translate to load in a bunch of language .json files.
Everything is working fine, but I'm trying to figure out how to basically "re-run the $translateProvider" so it can reload all the static files all over again as the .json files will get updated from the server periodically. I have yet to figure this out, and even trying to force a "page reload" doesn't cause the static files to reload.
I should note that I'm currently testing this in iOS and I realize that the directory structure will change, based on OS.
Here is my service that utilizes $cordovaFile to overwrite the file with new text. Right now I'm just using a simple json string to make sure I can solve the problem:
(function() {
'use-strict';
angular.module('coursemill.services')
.service('Translations', Translations);
/**
* Service: Check network connection
*/
function Translations($cordovaFile) {
function updateLanguageFile(lang) {
document.addEventListener("deviceready", function() {
$cordovaFile.checkFile(cordova.file.applicationDirectory + "/www/languages/", lang + ".json")
.then(function (success) {
// Update the language file
$cordovaFile.writeFile(cordova.file.applicationDirectory + "/www/languages/", lang + ".json", '{"COURSES_MENU_REQUIRED": "Required"}', true)
.then(function (success) {
// TO-DO: reload translation files
},
function (error) {});
},
function (error) {});
});
}
return {
updateLanguageFile: updateLanguageFile
}
}
})();
Here is a snippet from my .config:
// Setup the language translations
$translateProvider.useStaticFilesLoader({
prefix: 'languages/',
suffix: '.json'
});
Here is a snippet from my controller:
Translations.updateLanguageFile('en_US');
When I open the file up after this function has been run, the contents of the file are replaced and are doing exactly what I want, but I'd like my language variables inside the app to be updated as well, and they aren't.
Any thoughts on what can be done here?

Doink, I needed to use $translate.refresh() in my service function. So now it looks like this:
(function() {
'use-strict';
angular.module('coursemill.services')
.service('Translations', Translations);
function Translations($cordovaFile, $translate) {
function updateLanguageFile(lang) {
document.addEventListener("deviceready", function() {
$cordovaFile.checkFile(cordova.file.applicationDirectory + "/www/languages/", lang + ".json")
.then(function (success) {
// Update the language file
$cordovaFile.writeFile(cordova.file.applicationDirectory + "/www/languages/", lang + ".json", '{"COURSES_MENU_REQUIRED": "Required"}', true)
.then(function (success) {
// Reload translation files
$translate.refresh();
},
function (error) {});
},
function (error) {});
});
}
return {
updateLanguageFile: updateLanguageFile
}
}
})();

Related

get source of selected file in ionicframwork

I am building a mobile app using ionic. One of the usecase is to let the user browse a file and upload it to the backend server (which exposes a rest service).
On the UI, I am using the html file tag.
<input type="file" ng-select="uploadFile($files)" multiple>
.controller('UploadDocCtrl', function ($scope, $cordovaFileTransfer) {
$scope.uploadFile = function(files) {
console.log("selected file "+files);
// hard coded file path "/android_asset/www/img/ionic.pdf" to be replaced with the user selected file
$cordovaFileTransfer.upload(restServiceEndpoint, "/android_asset/www/img/ionic.pdf", properties).then(function(result) {
console.log("SUCCESS: " + JSON.stringify(result.response));
}, function(err) {
console.log("ERROR: " + JSON.stringify(err));
}, function (progress) {
// constant progress updates
});
});
The problem is that I am not able to get a reference to the selected file. Can someone please help with the steps to achieve this. Thanks!
Keep file in www folder which has index.html file.
then just give path like "ionic.pdf"
.controller('UploadDocCtrl', function ($scope, $cordovaFileTransfer) {
$scope.uploadFile = function(files) {
console.log("selected file "+files);
// hard coded file path "/android_asset/www/img/ionic.pdf" to be replaced with the user selected file
$cordovaFileTransfer.upload(restServiceEndpoint, "ionic.pdf", properties).then(function(result) {
console.log("SUCCESS: " + JSON.stringify(result.response));
}, function(err) {
console.log("ERROR: " + JSON.stringify(err));
}, function (progress) {
// constant progress updates
});
});

Visual Studio 2015 update3/cordova update 10 bug for apk building?

I've updated my Visual Studio to "Update 3" and the newest cordorva as of 7/7/2016, basically I applied all the updates. And it seems failed my app.
There is the following code in the html file templates\events.html.
<div class="events-2colmn-l backgnd-cover" ui-sref="menu.music">
MUSIC
</div>
In route.js
.state('menu.music', {
url: '/music',
views: {
'side-menu21': {
templateUrl: 'templates/music.html',
controller: 'musicCtrl'
}
}
})
There is a service.js file.
angular.module('app.services', ['ngResource'])
.factory('EventService', ['$resource', function ($resource) {
return $resource('https://....azurewebsites.net/api/events/:id', { id: "#id" });
}]);
And in the controller there is
.controller('musicCtrl', function ($scope, EventService) { // called twice when clicked
var allEvents = EventService.query({ category: "Music" });
allEvents.$promise.then(function (response) {
$scope.events = response; // response is undefined after updates
});
})
The parameter response is undefined when debugging using "Google Android Emulator" (Side-loading on phones got the same behaving so it should also get undefined). However, response got the right value when running in Ripple or built by Visual studio before applying the updates.
Is there any workaround?
Update:
I clicked the earliest call in "Call STack" when debugging in emulator and find the following code was called in ionic.bundle.js.
xhr.onload = function requestLoaded() {
var statusText = xhr.statusText || ''; // statusText is "Not found" but xhr is null
......
completeRequest(callback, // call stack
status, // 404
response, // ""
xhr.getAllResponseHeaders(), // xhr is null
statusText); // Not found
However the cursor on status and it shows 404. The url has the correct value of "https://....azurewebsites.net/.....".
And I tried opening a browser in emulator and I can access internet the link and got the webapi output.
Update 2:
There is one thing different between ripple and emulator. I set breakpoints as following. The ripple will break on both after click the item. However, in emulator, the first time the code will only break on the first breakpoint, continue running then break both the breakpoints.
.controller('musicCtrl', function ($scope, EventService) {
var allEvents = EventService.query({ category: "Music" }); // Emulator stops twice here
allEvents.$promise.then(
function (response) {
$scope.events = response; }, // Ripple stops here after one top break
function (e) {
console.log(e); } // Emulator stops here after two top breaks
);
})

Barcode Scanner using Ionic/ngcordova, not getting data

I've got a controller:
.controller('BarCodeScanCtrl', function($scope, $cordovaBarcodeScanner) {
$scope.scanBarcode = function() {
$cordovaBarcodeScanner.scan().then(function(barcodeData) {
// Success! Barcode data is here
console.log(barcodeData.text);
alert('barcode scanned:' + barcodeData);
}, function(error) {
alert('Error');
console.log(error);
// An error occurred
});
};
});
I'm using the QR code generator: http://www.qr-code-generator.com/ but I can't seem to retrieve any of the data I'm inputting. It's returning the barCode object the values of text & format properties are empty. The cancel property is true.
{
"cancelled": true,
"text":"",
"format": ""
}
Any ideas?
Have uploaded a working sample in github, please have a look.
Steps:
1) Create a project
2) cd into the project 3) Add required platforms
4) Add ngcordova-min.js file to the js folder 5) Add the ngcordova
js file path in index.html just before cordova path 6) Add ngcordova
dependancy to app.js 7) Add plugin 8) Add the function in html page
9) Add the logic in controller 10) Test the app
I supposed you are using Ionic. You should use on-touch directive from ionic not ng-click, because somehow when you are using ng-click it triggered the scan view twice and cause a force quit (CMIIW).
use it like this in your views:
<button on-touch="scanBarcode()">Scan</button>
Hope it works!
If the cancel property is true you stop the scanning function manually.
inject $ionicPlatform in your controller
.controller('BarCodeScanCtrl', function($scope, $cordovaBarcodeScanner, $ionicPlatform) {
$scope.scanQR = function () {
$ionicPlatform.ready(function() {
$cordovaBarcodeScanner.scan()
.then(function(barcodeData) {
alert('result = '+barcodeData.text);
alert('type = '+barcodeData.format);
alert('cancelled = '+barcodeData.cancelled);
}, function(error) {
alert(error);
});
});
}
});

How to create and use separate file for each language in angular-translate with requirejs-angularAMD?

Using angualr-translate with requirejs. Want to create separate files for each language (contains translate keys), for the time it is all in app.js.
Example- app.js
define(['angularAMD', 'ngRoute','pascalprecht.translate'], function (angularAMD) {
var app = angular.module('app', ['ngRoute','pascalprecht.translate']);
app.config(['$routeProvider','$translateProvider', function($routeProvider,$translateProvider){
/* *************** routes *************** */
//...........
/* *************** routes *************** */
/* angular translate */
$translateProvider.translations('en', {
add_user: 'Add User',
first_name:'First Name',
last_name:'Last Name',
//.....
//IMPORTANT: more than 1000 translate keys...
//.....
});
$translateProvider.translations('de', {
add_user: 'Benutzer hinzufügen',
first_name:'Vorname',
last_name:'Last Name',
//.....
//IMPORTANT: more than 1000 translate keys...
//.....
});
// Bootstrap Angular when DOM is ready
return angularAMD.bootstrap(app);
});
For case you want to use js instead of JSON.
var app = angular.module('myModule', []);
app.config(function ($translateProvider) {
$translateProvider.useLoader('customLoader', {
// if you have some custom properties, go for it!
});
});
app.factory('customLoader', function ($http, $q) {
// return loaderFn
return function (options) {
var deferred = $q.defer();
// do something with $http, $q and key to load localization files
// or do something to load file with requireJS
require(['en-US'], function(translation){
var data = translation;
}
return deferred.resolve(data);
// or
return deferred.reject(options.key);
};
});
this is an modified example in the preference link of asynchronus-loading in the end of the answer (section Using custom loader service)
OLD ANSWER
angular-translate supports on-demand load for translation files. You don't need to use requireJS in this case.
Currenly this is my code in app.config()
$translateProvider.useUrlLoader('/translate');
$translateProvider.preferredLanguage('en');
$translateProvider.fallbackLanguage('en');
all you need to do is setup url like below
{your_host}/something-translate?lang={language_key}
In my case, the server real url is like.
localhost/translate?lang=en
localhost/translate?lang=fr
localhost/translate?lang=es
...
Then in controller:
$scope.translate = function (langKey){
$translate.use(langKey);
}
Preference link:
https://github.com/angular-translate/angular-translate/wiki/Asynchronous-loading#registering-asynchronous-loaders
https://github.com/angular-translate/angular-translate/wiki/Extensions

Parse.initialize breaking Angular Cordova app in iOS simulation

So I have an app in angular with cordova, that works as expected when served to a local web host, pushing and pulling the login data from parse.com.
But, when I compile and emulate in an IOS emulator, it appears that the command
parse.initialize("453ioejblahgf3oi5j35p","f30903959fblahblah");
is making $state.go fail to work.
:(
Upon closer inspection, it seems as though Parse.initialize("faerfaerfaerf";"aefaerfeafaer"); is putting a stop to all code that comes after it --
$scope.registerNowClick = function (user) {
//Copy the user to $scope.tmpUser
$scope.tmpUser = angular.copy(user);
// PARSE INITILIZATION CALL Parse.initialize("Zmqvefjaeifai34jofewOvRDxfNdoxH", "HlzTePUSi3fja305f0j341");
alert('Register Now was clicked w/ Email:' + $scope.tmpUser.email);
// PARSE ADD A USER
var user = new Parse.User();
user.se blah blah
If I move the alert above the parse.init, it fires. But when it's after the parse.init, it doesn't.
Javascript is interpreted language. Meaning that, any run-time errors wont halt the program, until that particular line is reached.
Looking at your problem, it looks like Object Parse is not defined. Have you included any parse.js files that it may require? Move Parse.initialize() to the end of the script so that it wont halt the rest of the code from executing.
I have put my Parse initialization in a separate UserService.init() that must be resolved at app startup.
.state('tab', {
url: "/tab",
abstract: true,
templateUrl: "templates/tabs.html",
resolve: {
user: function (UserService) {
var value = UserService.init();
// alert(value); // for debugging
return value;
}
}
})
Here is a snippet of the UserService code
init: function () {
var value = null;
var deferred = $q.defer();
// if initialized, then return the activeUser
if (parseInitialized === false) {
Parse.initialize(ParseConfiguration.applicationId, ParseConfiguration.javascriptKey);
parseInitialized = true;
console.log("parse initialized in init function");
}
setTimeout(function () {
var currentUser = Parse.User.current();
if (currentUser) {
deferred.resolve(currentUser);
} else {
deferred.reject({error: "noUser"});
}
}, 100);
return deferred.promise;
},
The complete solution is here ... https://github.com/aaronksaunders/dcww

Resources