Error: Cannot read property 'replace' of undefined when building iOS Cordova Error: Cannot read property 'replace' of undefined when building iOS Cordova ios ios

Error: Cannot read property 'replace' of undefined when building iOS Cordova


New solution

This issue is fixed in the latest version of the "ios-sim" package (so now this is probably the easier solution - compared to the old one which is listed below). In order to update the "ios-sim" package to the latest version run this in your terminal/cmd:

cd platforms/ios/cordova/node_modules/sudo npm install -g ios-sim@latest

Old solution

The problem is that the name_id_map[deviceName] returns undefined for "iPad Pro (12.9-inch)" and "iPad Pro (10.5-inch)".

You can check it with a console.log('name_id_map[ deviceName ]: ' + name_id_map[ deviceName ]);.

I fixed this bug by adding an if statements which checks if the device is defined in "platforms/ios/cordova/node_modules/ios-sim/src/lib.js:282".

I replaced this:

list = [];        var remove = function(runtime) {            // remove "iOS" prefix in runtime, remove prefix "com.apple.CoreSimulator.SimDeviceType." in id            list.push(util.format('%s, %s', name_id_map[ deviceName ].replace(/^com.apple.CoreSimulator.SimDeviceType./, ''), runtime.replace(/^iOS /, '')));        };

with this:

list = [];        var remove = function(runtime) {            // remove "iOS" prefix in runtime, remove prefix "com.apple.CoreSimulator.SimDeviceType." in id            if (name_id_map[deviceName] && runtime) {                list.push(util.format('%s, %s', name_id_map[deviceName].replace(/^com.apple.CoreSimulator.SimDeviceType./, ''), runtime.replace(/^iOS /, '')));            }        };

The "iPad Pro (10.5-inch)" simulator won't be on the list (but it doesn't probably work anyway - didn't check).

Bug report on github: https://github.com/phonegap/ios-sim/issues/210


in your project folder root, do cd platforms/ios/cordova && npm install ios-sim


I had the same error. For me I traced this down into a bug in platforms/ios/cordova/node_modules/ios-sim/src/lib.js

getdevicetypes: function(args) {...    list.devicetypes.forEach(function(device) {        name_id_map[ filterDeviceName(device.name) ] = device.id;    });    list = [];    var remove = function(runtime) {        // remove "iOS" prefix in runtime, remove prefix "com.apple.CoreSimulator.SimDeviceType." in id        list.push(util.format('%s, %s', name_id_map[ deviceName ].replace(/^com.apple.CoreSimulator.SimDeviceType./, ''), runtime.replace(/^iOS /, '')));    };

The error always occured as "TypeError: Cannot read property 'replace' of undefined" in lib.js:289

list.push(util.format('%s, %s', name_id_map[ deviceName ].replace(/^com.apple.CoreSimulator.SimDeviceType./, ''), runtime.replace(/^iOS /, '')));

So I inserted some debug code:

    list.devicetypes.forEach(function(device) {        console.log('test 1 ' + device.name);        console.log('test 2 ' + filterDeviceName(device.name));        name_id_map[ filterDeviceName(device.name) ] = device.id;    });

This worked for me. Good luck.

    list = [];    var remove = function(runtime) {        // remove "iOS" prefix in runtime, remove prefix "com.apple.CoreSimulator.SimDeviceType." in id        console.log('remove 1 ' + runtime);        console.log('remove 2 ' + deviceName);        console.log('remove 3 ' + name_id_map[ deviceName ]);        list.push(util.format('%s, %s', name_id_map[ deviceName ].replace(/^com.apple.CoreSimulator.SimDeviceType./, ''), runtime.replace(/^iOS /, '')));    };

and got the following output:

test 1 iPhone 5test 2 iPhone 5test 1 iPad Pro (9.7-inch)test 2 iPad Pro (9.7 inch)remove 1 iOS 10.2remove 2 iPhone 5remove 3 com.apple.CoreSimulator.SimDeviceType.iPhone-5remove 1 iOS 10.2remove 2 iPad Pro (9.7-inch)remove 3 undefined

Notice how filterDeviceName removed the minus character while filling the hash. When the value is retrieved again, the filter is not applied and the program fails.

Bug fix: apply the filter while writing to and reading from the hash.

 list.push(util.format('%s, %s', name_id_map[ filterDeviceName(deviceName) ].replace(/^com.apple.CoreSimulator.SimDeviceType./, ''), runtime.replace(/^iOS /, '')));