SentryError: Native Client is not available, can’t start on native when updating expo-cli to 4.x.x (from version 3.22.3)

TL;DR: Update your metro.config.js to use @expo/metro-config based on the latest guidelines (SDK 40+) –

It’s funny when you encounter an error in a project, and after spending a lot of effort researching it, to find out that the cause is the same with a totally different error on a very different project.

In my case this was caused by outdated metro.config.js file, specifically the SVG loading code that uses react-native-svg-transformer.

To fix it, I replaced the metro config with the following:

const { getDefaultConfig } = require("@expo/metro-config");

module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts }
  } = await getDefaultConfig(__dirname);
  return {
    transformer: {
      babelTransformerPath: require.resolve("react-native-svg-transformer")
    },
    resolver: {
      assetExts: assetExts.filter(ext => ext !== "svg"),
      sourceExts: [...sourceExts, "svg"]
    }
  };
})();

And also intall the '@expo/metro-config' module:

yarn add @expo/metro-config
// or
npm install @expo/metro-config

More info on the other error – SVG Icons Not Loaded After Updating ReactNative Expo to Version 40

Cheers!

jQuery error .apply( matched.elem, args ); undefined is not a function

If you’re having an error in your site/app that says that is undefined is not a function and the error happens on the row containing .apply( matched.elem, args ); (jquery.js:4676 for version 2.0.3). You can do the following 2 things to figure out the error:

0. You need Chrome Dev Tools
1. Enable async for your dev tools
2. See in the call stack which is your file that attached the event listener and more important – which event was the one that is currently being handled. Mind that the funciton that is attaching to the event causing the error is highly likely that is not the problematic one. Usualy the problematic event subscription is one that cannot be invoked so probably you won’t see it in the list.
3. Look through your site/app for attaching a handler to the problematic event that is not defined. Remember – the event is the important part, not the selector.

For example

function myHandler ( event ){ console.log( 'jquery rulez!' ); }

$( document ).on( 'change', '.otherInput', function() {
 console.log( 'Yeah!' );
});

$( document ).on( 'change', '.myInput', myHandlerFunction );

In this case the myHandlerFunction is not defined (maybe because we forgot to rename it). So on the change called it will give us the error that undefined is not a function.

It was really annoying trying to figure out what did just break since the problem will happen on every triggering of any change event in the document.

Cheers and follow me on twitter

Adding a custom attribute to an existing sencha touch component (and why it might cause error after production build)

Lately we’ve been using Sencha Touch for an interesting project. We found a problem which something was working correctly while on develop mode but stopped working after the app was built for production.

Turned out the problem was becuase we added a custom attribute to an existing sencha component which we wanted to use.

Ext.define('SomeView', {
	extend: 'Panel',
	...,
	config: {
		...,
		items: [{
			id: 'myCustomContainer',
			xtype: 'Container',
			customAttribute: 'customValue'
		}]
	}
});

And afterwards tried to get the custom attribute from the specific Custom Container (let’s say stored in variable myCustomContainer) as:

myCustomContainer.customAttribute

This works correctly if the app is tested without building it for production but gives an JS error when in the built for production app it tries to access the custom attribute.

The correct way to do so is simply to define a custom container that inherits the built-in one and put the custom attribute in it’s config with it’s default value.

Ext.define('MyCustomContainer', {
	extend: 'Ext.Container',
	xtype: 'myCustomContainer',
	config: {
		myCustomAttribute: null
	}
});

Now you can use the xtype ‘myCustomContainer’ instead of ‘Container’ in the view and Sencha automatically creates a getter and a setter for it.

To use (get/set) the custom attribute you can do something like this:

// if we want to set it
myCustomContainer.getMyCustomAttribute();
// or if we want to set it:
myCustomContainer.setMyCustomAttribute('NewValue');

And now after the production build the app works again

Update to WooCommerce 2.0 and missing information for the product (in the front-end)

WooThemes released the new WooCommerce 2.0 recently and updating seems really charming with the new interface and other listed features.

However sometimes updating won’t be the best thing you can do if your theme is made for 1.6.

In non-technical words – if after the update some of the information is missing or is wrong when seeing it in the front-end this is most related to the theme.

The problem here is that many theme developers (even WooThemes themselves) are using the WC_Product to get the product’s data. The problem is that you can no longer create an instance of WC_Produc by post ID. This is probably related to the new function get_product() which I think is really poorly documented in their official docs for some thing to put in the new release information.

In my case for a theme made from WooThemes themselves I had:

//inside the loop
$_product = &new WC_Product( $loop->post->ID );

This would no longer work so I changed it to

$_product = get_product(  $loop->post->ID );

Which fixed it right away.

In my opinion it would be good if they could update their own existing themes to work with the new version insead of just not caring what their end-users would end up with.

JS Date object and iOS Safari

Safari on iOS is probably one of the best mobile browsers. Still there is one thing that I often got wrong and wonder why my webapp doesn’t work.

Javascript Date Object in iOS Safari

In every normal browser you could just create a Date object from string as

var myDate = new Date('2013-01-21T13:46:20');

But on iOS this simply gives you a JS error.

To fix it you should use the good ol’ split() and do something like this

//First we split the date string
var iosDateArr = '2013-01-21T13:46:20'.split('[- :T]');
//And use the constructor with 6 args
cDate = new Date(arr[0], arr[1]-1, arr[2], arr[3], arr[4], arr[5]);

Note that the Month in the array is reduced by one. This is because the Months are counted from 0 for January to 11 for December.