How do you debug a realm database that’s on a physical device?

This dev tip is brought to you by the developer of Moolabeast: Automated Expense Tracking for Android and iOS. Avoid overspending when you start tracking your expenses with Moolabeast.

Alright, so let’s get to it: How to debug a realm database running on a physical device:

Unfortunately, you cannot debug a realm database running on a physical device if it is already in production.

Hopefully this saves someone out there a ton of heartache, but after you have pushed your app out in to production, you can’t just open up a .realm file from your device using Realm Studio due to security restrictions. So if you happen to find yourself struggling to open a realm database that’s running on your personal device, and can’t seem to access the .realm file to debug it, it could be that your device isn’t allowing access to the file because it is a production app and is not debuggable via USB and Android Studio, etc.

Now, if you need to debug a development version of your app, it’s a different story. You can simply open up your app in Android Studio, with your physical device plugged into your computer, and open up the Device File Explorer in Android Studio, where you will be able to locate your .realm database file. From the Device File Explorer you can right-click and save the .realm file onto your computer and open it using Realm Studio.

If you need to be able to debug and inspect Realm database instances running on live production versions of your app, this may be possible with Realm’s new Realm Cloud product. However, I haven’t checked out Realm Cloud and Realm Sync just yet as I’m still getting my feet wet with Realm DB.

 

How to use ON DUPLICATE KEY UPDATE with Python, MySQL, and mysql.connector

This dev tip is brought to you by the developer of Moolabeast: Automated Expense Tracking for Android and iOS. Avoid overspending when you start tracking your expenses with Moolabeast.

Fret not distressed developer! Using the ON DUPLICATE KEY UPDATE feature of SQL with Python, MySQL, and mysql.connector can be a bit of a doozy once you add in parameterizing your queries. This personally took me quite awhile to figure out since most of the SQL references regarding ON DUPLICATE KEY UPDATE do not include the Python/mysql.connector specific aspects, and most of the Python/mysq.connector references do not mention ON DUPLICATE KEY UPDATE.

So here is the trick, you won’t be passing the SQL query values like usual with %s for the UPDATE part of your query. Instead you will write something like VALUES(name_column). For reference, here is a little snippet of code from one of my projects which should guide you in the right direction:

import mysql.connector
# Create MySQL Database Connection
database_connection = mysql.connector.connect(
host="99.111.11.99", # dummy ip address
user="your-super-sweet-admin-name",
passwd="y0uRpAsSw0Rd",
database="your_db"
)
cursor = database_connection.cursor()
values = (
"myTransactionID",
"myUserID",
"myName",
9.99,
"myCategoryA",
"myCategoryB",
"myCategoryC",
123,
"1970-01-01",
"XYZ",
"myAddress",
50.0,
50.0,
"CA",
"90210",
1,
"myTransactionType") # single tuple will hold one row worth of database data
sql = "\
INSERT INTO transaction_table \
(transaction_id_column, \
user_id_column, \
name_column, \
amount_column, \
category_a_column, \
category_b_column, \
category_c_column, \
category_id_column, \
date_column, \
iso_currency_code_column, \
address_column, \
lat_column, \
lon_column, \
state_column, \
zip_column, \
pending_column, \
transaction_type_column) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) \
ON DUPLICATE KEY UPDATE \
user_id_column = VALUES(user_id_column), \
name_column = VALUES(name_column), \
amount_column = VALUES(amount_column), \
category_a_column = VALUES(category_a_column), \
category_b_column = VALUES(category_b_column), \
category_c_column = VALUES(category_c_column), \
category_id_column = VALUES(category_id_column), \
date_column = VALUES(date_column), \
iso_currency_code_column = VALUES(iso_currency_code_column), \
address_column = VALUES(address_column), \
lat_column = VALUES(lat_column), \
lon_column = VALUES(lon_column), \
state_column = VALUES(state_column), \
zip_column = VALUES(zip_column), \
pending_column = VALUES(pending_column), \
transaction_type_column = VALUES(transaction_type_column)"
cursor.execute(sql, values)
database_connection.commit()
 

How to Programmatically Submit Websites & Webpages to the Internet Archive’s Wayback Machine

Welcome back internet friend,

Tonight I started hacking on an old project on which I’m currently bringing back to life, a chrome extension which saves all of the pages you visit to the Internet Archive’s Wayback Machine. It’s called The Internet Archivist’s Intrepid Extension.

Unfortunately I had to kill off the first version of the extension because cloudflare started blocking all of my traffic. However, I discovered today that Archive.org has an API for submitting links programmatically. So the Intrepid Extension is back!

After an hour or so of hacking I’ve put together a pretty simple prototype and thought maybe I should share the source code here on the blog in case anyone else is stumbling around the internet looking for a solution. Enjoy!

<!DOCTYPE html>
<html>
<body>
<input id="urlInput" type="text" size="40" placeholder="Enter URL to Archive">
<button onclick="archive();">ARCHIVE</button>
<script>
var data;
function archive() {
var urlInput = document.getElementById('urlInput');
var url = document.getElementById('urlInput').value;
urlInput.value = ""; // clear url text input field
ajaxRequest = new XMLHttpRequest();
if (!ajaxRequest) {
alert("ERROR 0001: PC LOAD LETTER");
return; // kill, do not run rest of function
}
// json data which we will be sending to the server via ajax
data = {
"url": url
};
ajaxRequest.onreadystatechange = function() {
if (ajaxRequest.readyState === XMLHttpRequest.DONE) {
if (ajaxRequest.status === 200) {
// raw server response, may need to parse JSON if
// the server you are pinging will be responding
// with JSON
var serverResponse = ajaxRequest.responseText;
console.log(serverResponse);
alert(serverResponse);
} else {
alert("ERROR 0002: PC LOAD LETTER ");
}
}
};
ajaxRequest.open('POST', "https://pragma.archivelab.org");
ajaxRequest.setRequestHeader('Content-type', 'application/json');
ajaxRequest.send(JSON.stringify(data));
}
</script>
</body>
</html>
view raw send-wayback.html hosted with ❤ by GitHub
 

FatCamp Privacy Policy

Privacy Policy

Your privacy is important to me. It is  my (Christopher Pedersen) policy to respect your privacy regarding any information I may collect from you on my app, FatCamp.


I only ask for personal information when we truly need it to provide a service to you. I collect it by fair and lawful means, with your knowledge and consent. I also let you know why I am collecting it and how it will be used.


I only retain collected information for as long as necessary to provide you with your requested service. What data I store, I will protect within commercially acceptable means to prevent loss and theft, as well as unauthorized access, disclosure, copying, use or modification.
I don’t share any personally identifying information publicly or with third-parties, except when required to by law.


My app may link to external sites that I do not operate. Please be aware that I have no control over the content and practices of these sites, and cannot accept responsibility or liability for their respective privacy policies.


You are free to refuse our request for your personal information, with the understanding that I may be unable to provide you with some of your desired services.


Your continued use of my website will be regarded as acceptance of our practices around privacy and personal information. If you have any questions about how I handle user data and personal information, feel free to contact me (chris@topherpedersen.com).


This policy is effective as of 4 December 2019.

 

TODO List in VanillaJS (for teaching purposes)

<!DOCTYPE html>
<html>
<head>
<!-- Mobile Friendly Meta Tag -->
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1>Vanilla TODO</h1>
<input type="text" id="newItem">
<button onclick="addToList();">+</button>
<ul id="todoList"></ul>
<script>
function addToList() {
var task = document.getElementById("newItem").value;
var thingtoadd = document.createElement("LI");
thingtoadd.innerHTML = task;
thingtoadd.id = Math.random().toString();
var removebutton = document.createElement("BUTTON");
removebutton.innerHTML = "X";
removebutton.onclick = function() {
removeFromList(thingtoadd.id);
};
thingtoadd.appendChild(removebutton);
// thingtoadd.innerHTML += removebutton;
var todoList = document.getElementById("todoList");
todoList.appendChild(thingtoadd);
/*
thingtoadd.onclick = function() {
removeFromList(thingtoadd.id);
};
*/
console.log(task);
}
function removeFromList(id) {
var todoList = document.getElementById("todoList"); // parent
var itemToBeRemoved = document.getElementById(id); // child
todoList.removeChild(itemToBeRemoved);
}
</script>
</body>
</html>
view raw vanilla-todo.html hosted with ❤ by GitHub
 

React Native error Failed to install the app… com.android.ddmlib.InstallException: INSTALL_FAILED_UPDATE_INCOMPATIBLE: Package signatures do not match previously installed version; ignoring!

This dev tip is brought to you by the developer of Moolabeast: Automated Expense Tracking for Android and iOS. Avoid overspending when you start tracking your expenses with Moolabeast.

error Failed to install the app. Make sure you have the Android development environment set up: https://facebook.github.io/react-native/docs/getting-started.html#android-development-environment. Run CLI with –verbose flag for more details.

Error: Command failed: gradlew.bat app:installDebug -PreactNativeDevServerPort=8081

Unable to install C:\Users\you\Desktop\YourApp\android\app\build\outputs\apk\debug\app-debug.apk

com.android.ddmlib.InstallException: INSTALL_FAILED_UPDATE_INCOMPATIBLE: Package com.yourapp signatures do not match previously installed version; ignoring!

O man, what a doozy!?! Okay so here’s what’s probably going on, or at least what has been going on the several times I’ve run into this error. I happen to do development on several different computers, but use the same physical android device to test my app. So what happens is, the signature attached to the app installed on our physical android device, doesn’t match the signature of the computer that we’ve moved to and are now working.

However, the fix is fairly simple. All you need to do is delete the app from your physical device, then re-build/run your app again and all shall be well!

$ npx react-native run-android

or…

$ react-native run-android

 

Connection is not secure— How to Add the Lock Symbol to Your Website for Free with Certbot

Welcome back dear internet friends,

In this post I want to talk a little bit about HTTP vs HTTPS, the lock symbol or lock icon that appears next to your website’s address in the web browser, and how you can add all this encrypted goodness to your website for free with Certbot!

Let’s do it

$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository universe
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install certbot python-certbot-apache
$ sudo certbot --apache
view raw encrypt.sh hosted with ❤ by GitHub
 

Working with Dollars and Cents in JavaScript: The Definitive Guide

Why hello there dear internet friend!

Welcome to my blog and the “definitive guide” on working with dollars and cents in JavaScript 😉 So the title of this post is a bit misleading, all you really need is one nifty method to format your numbers as dollars and cents:

yourNumberVariable.toFixed(2)

That’s it! Pretty nifty right?

I currently happen to be working on a personal finance app called Moolabeast at the moment, so that’s why I decided to publish this post. After releasing the latest version of the app I noticed a bug that was causing some of my financial transactions to format something like $ 34.089999999999996 , yikes! Thus the interest in this topic.

Previously I was using some one-liner of JavaScript I found on StackOverflow for formatting my dollar amounts. The line of code I was using had some wonky regular expression in it that I did not understand or care to investigate further until things went awry in my app. However, after digging into how this little code snippet worked, I discovered that the only part that really mattered was the toFixed method. I had assumed that this regular expression was important for… something? However, I was wrong! You really just need toFixed and you are good to go.

If you’d like a reference to play around with, check out my “definitive guide” below:

(UPDATE 11/26/2019: It looks like the regex was for adding commas, whoops! If you need commas, which I assume you do, check the last section of the code sample below for the regex magic.)

(UPDATE: 11/30/2019: The regex magic described above does not work with floating point numbers represented as strings. One could write a regular expression that does work with whole numbers, however, I’m not very good with writing regular expressions. Therefore, I’ve included a little function which I wrote in case anyone needs to add commas to whole numbers.)

console.log("****************************************************");
console.log("**** Working With Dollars & Cents in JavaScript ****");
console.log("**** ~ The Definitive Guide ~ ****");
console.log("****************************************************");
console.log('\n');
const formatAsDollarsAndCents = (value) => {
var newValue = parseFloat(value);
newValue = newValue.toFixed(2);
return newValue;
}
// Floating Point Numbers Formatted to 2 Decimal Places
console.log("Floating Point Numbers Formatted to 2 Decimal Places");
const nonStandardAmountFormatted = formatAsDollarsAndCents(34.089999999999996);
console.log(nonStandardAmountFormatted);
const oneDecimalPlaceFormatted = formatAsDollarsAndCents(1.1);
console.log(oneDecimalPlaceFormatted);
const wholeNumberFormatted = formatAsDollarsAndCents(1);
console.log(wholeNumberFormatted);
console.log('\n');
// Strings Formatted to 2 Decimal Places
console.log("Cast As String...");
const nonStandardAmountFormattedAsString = nonStandardAmountFormatted.toString();
console.log('$' + nonStandardAmountFormattedAsString);
const oneDecimalPlaceFormattedAsString = oneDecimalPlaceFormatted.toString();
console.log('$' + oneDecimalPlaceFormattedAsString);
const wholeNumberFormattedAsString = wholeNumberFormatted.toString();
console.log('$' + wholeNumberFormattedAsString);
console.log('\n');
// Need to add commas? Here's the regex magic sprinkled in...
const myNumber = 1300000.89
const myNumberAsString = myNumber.toString();
const myNumberWithCommas = myNumberAsString.replace(/\d(?=(\d{3})+\.)/g, '$&,');
console.log('Add commas... ');
console.log('$' + myNumberWithCommas);
// Edge case, need to add commas to a whole number? I've written a function that
// will add commas to a string of numeric characters. This is helpful when working
// with integers, as the regular expression above does not work with whole numbers.
// (One could write a regular expression that works with whole numbers, but I'm not
// very good with regex so I just wrote a function and moved on with my life 😉
function getWholeNumberWithCommas(wholeNumberStr) {
// Step One, Reverse String
var reversedString = "";
var indexOfLastChar = wholeNumberStr.length - 1;
for (var i = indexOfLastChar; i >= 0; i--) {
reversedString = reversedString + wholeNumberStr[i];
}
// Step Two, Add Commas Every Third Char
var reversedStringWithCommas = "";
for (var i = 0; i < reversedString.length; i++) {
// every third char, add a comma and the next char
if (i % 3 === 0 && i !== 0) {
reversedStringWithCommas = reversedStringWithCommas + "," + reversedString[i];
} else {
reversedStringWithCommas = reversedStringWithCommas + reversedString[i];
}
}
// Step Three, Reverse reversedStringWithCommas, and we'll have
// the whole number with commas that we want
var wholeNumberWithCommas = "";
indexOfLastChar = reversedStringWithCommas.length - 1;
for (var i = indexOfLastChar; i >= 0; i--) {
wholeNumberWithCommas = wholeNumberWithCommas + reversedStringWithCommas[i];
}
// Step Four, return wholeNumberWithCommas
return wholeNumberWithCommas;
}
console.log('\n');
var testNumber = "9283749823749872398472938742983748";
var testNumberWithCommas = getWholeNumberWithCommas(testNumber);
console.log('Add commas to a whole number (represented as a string)');
console.log(testNumberWithCommas);
console.log('\n');
console.log("****************************************************");
console.log("****************************************************");
console.log("****************************************************");
view raw dollars_and_cents.js hosted with ❤ by GitHub
 

Getting Started with Redux, Batteries Included, No Assembly Required

Playing around with Redux this morning and didn’t like the fact that you have to use npm and whatnot to compile modules to run the simple example? Seemed overly complicated, so here’s a little demo with no compilation or development server required:

<!DOCTYPE html>
<html>
<head>
<script src='https://cdnjs.cloudflare.com/ajax/libs/redux/3.7.2/redux.min.js'></script>
</head>
<body>
<h1>Redux Quickstart<h1>
<h2>Count: <span id="counter">0</span></h2>
<button onclick="increment();">+</button>
<button onclick="decrement();">-</button>
<p>https://redux.js.org/introduction/getting-started</p>
<script>
function changeState(state = 0, action) {
switch(action.type) {
case 'INCREMENT':
return state + 1;
case 'DECREMENT':
return state - 1;
default:
return state;
}
}
let store = Redux.createStore(changeState);
store.subscribe( () => {
document.getElementById('counter').innerHTML = store.getState();
});
function increment() {
store.dispatch({ type: 'INCREMENT' });
}
function decrement() {
store.dispatch({ type: 'DECREMENT' });
}
</script>
</body>
</html>