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

28,296

Solution 1

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

Solution 2

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

Solution 3

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 5
test 2 iPhone 5
test 1 iPad Pro (9.7-inch)
test 2 iPad Pro (9.7 inch)
remove 1 iOS 10.2
remove 2 iPhone 5
remove 3 com.apple.CoreSimulator.SimDeviceType.iPhone-5
remove 1 iOS 10.2
remove 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 /, '')));

Solution 4

There is a PR on Github which fixed my problem: https://github.com/phonegap/ios-sim/pull/213

Just called following inside my project root

nano platforms/ios/cordova/node_modules/ios-sim/src/lib.js

and added the function to filter the device name, as pointed out here: https://github.com/phonegap/ios-sim/pull/213/files

Solution 5

I recently upgreaded to xcode 8.3.3 and ionic 3.4.0

I have removed ios-sim directory from myApp/platforms/ios/cordova/node_modules and now it's working.

Share:
28,296

Related videos on Youtube

Shaun Cheng
Author by

Shaun Cheng

Passionate and experienced Full Stack expert in web and mobile application development. ★ Javascript/MERN/MEAN expert - React/Redux, Angular, TypeScript, Node.js, MongoDB, Vue.js, ES2017/2016, Webpack ★ LAMP Stack Web Developer - HTML5, CSS3, ROR Bootstrap, jQuery, Wordpress, Laravel, CodeIgnitor, Ajax, XML ★ Pro Mobile Expert - iOS, Android, Swift, Kotlin, Xamarin, React Native, Java

Updated on July 09, 2022

Comments

  • Shaun Cheng
    Shaun Cheng almost 2 years

    I created a cordova project using cordova create project hello com.hello Hello.

    And added iOS platform using cordova platform add iOS. And tried to do cordova run ios after cordova build ios.

    But it shows me this error(I used --d/ --verbose to get the details).

    /usr/bin/codesign --force --sign - --timestamp=none /Volumes/Untitled/Plot/PlotReel/platforms/ios/build/emulator/PlotReel.app /Volumes/Untitled/Plot/PlotReel/platforms/ios/build/emulator/PlotReel.app: replacing existing signature

    ** BUILD SUCCEEDED **

    No scripts found for hook "before_deploy". Error: TypeError: Cannot read property 'replace' of undefined

    at remove (/Volumes/Untitled/Plot/test/platforms/ios/cordova/node_modules/ios-sim/src/lib.js:282:70)
    at Array.forEach (native)
    at Object.getdevicetypes (/Volumes/Untitled/Plot/test/platforms/ios/cordova/node_modules/ios-sim/src/lib.js:292:22)
    at Object.listEmulatorImages [as run] (/Volumes/Untitled/Plot/test/platforms/ios/cordova/lib/list-emulator-images:34:29)
    at deployToSim (/Volumes/Untitled/Plot/test/platforms/ios/cordova/lib/run.js:146:50)
    at /Volumes/Untitled/Plot/test/platforms/ios/cordova/lib/run.js:88:20
    at _fulfilled (/Volumes/Untitled/Plot/test/platforms/ios/cordova/node_modules/q/q.js:834:54)
    at self.promiseDispatch.done (/Volumes/Untitled/Plot/test/platforms/ios/cordova/node_modules/q/q.js:863:30)
    at Promise.promise.promiseDispatch (/Volumes/Untitled/Plot/test/platforms/ios/cordova/node_modules/q/q.js:796:13)
    at /Volumes/Untitled/Plot/test/platforms/ios/cordova/node_modules/q/q.js:604:44
    

    I have tried uninstalling and installing cordova again, but the problem is still remaining.

    Please help me.

    • Shaun Cheng
      Shaun Cheng about 7 years
      cordova -v shows 6.5.0
    • Phonolog
      Phonolog about 7 years
      Have you tried running your command with the -d/--verbose option? Maybe you'll get some more information about your error...
    • Shaun Cheng
      Shaun Cheng about 7 years
      I just updated my question with error details. Thanks.
    • Gandhi
      Gandhi about 7 years
      @Phoenix Try clearing your npm cache once and create the project onc again using the steps you followed. command to clear npm cache - "npm cache clean" Hope it works. Keep me posted
    • Shaun Cheng
      Shaun Cheng about 7 years
      @Gandhi, Thank you, but it does not fix the issue, just tried it.
    • Gandhi
      Gandhi about 7 years
      @Phoenix In that case, the last option left out is to reinstall npm as npm modules seems to be corrupted in your case
    • Shaun Cheng
      Shaun Cheng about 7 years
      I also tried it, will do it again.
    • Gandhi
      Gandhi about 7 years
      @Phoenix try running the following command - "cordova -d build ios" This might give some more info about the failure so that we can narrow down the issue
    • Gandhi
      Gandhi about 7 years
      @Phoenix i m sorry. I overlooked at the question. Ok now i think i got the issue. Your issues seems to be with ios-sim command line utility. Ensure that you install the latest version of ios-sim. You cab check out this link for more info on an issue similar to this -github.com/phonegap/ios-sim/issues/203 This should hopefully resolve your issue
    • Shaun Cheng
      Shaun Cheng about 7 years
      I tried to run iso-sim showdevicetypes and got the following. iPhone-5, 10.1 iPhone-5s, 10.1 iPhone-6, 10.1 iPhone-6s, 10.1 iPhone-6s-Plus, 10.1 iPhone-7, 10.1 iPhone-7-Plus, 10.1 iPhone-SE, 10.1 iPad-Retina, 10.1 iPad-Air, 10.1 iPad-Air-2, 10.1 iPad-Pro--9-7-inch-, 10.1 iPad-Pro, 10.1 Apple-TV-1080p, tvOS 10.0 Apple-Watch-38mm, watchOS 3.1 Apple-Watch-42mm, watchOS 3.1 Apple-Watch-Series-2-38mm, watchOS 3.1 Apple-Watch-Series-2-42mm, watchOS 3.1
    • Shaun Cheng
      Shaun Cheng about 7 years
      I also reinstalled ios-sim using sudo npm install -g ios-sim, but it doesn't help me.
    • Ryad Boubaker
      Ryad Boubaker about 7 years
      Why dont you open your project with xCode ??
    • Shaun Cheng
      Shaun Cheng about 7 years
      It's also possible, i prefer working via terminal.
    • Gandhi
      Gandhi about 7 years
      @Phoenix What's your node and ios-sim version? i Still feel the link i sent earlier should have fixed your issue
    • Gandhi
      Gandhi about 7 years
      @Phoenix it could also be due to some privilege issues as mentioned here - github.com/phonegap/ios-sim/issues/183
    • Shaun Cheng
      Shaun Cheng about 7 years
      I need definite answers, please add your answers, not comments. Thanks.
    • Gandhi
      Gandhi about 7 years
      @Phoenix You gotta understand that these kinds of issues are setup and environment specific. Not everyone will face these issues on daily basis. So it can be solved only via trail and error process. So definite answers are hard to come by and even if comes, it will be a guess. Moreover posting answers based on assumptions and getting it down-voted is even worse. If you dont want suggestions, thats fine.
    • Matheus Abreu
      Matheus Abreu over 6 years
      The Old Solution works to me
  • Serdar D.
    Serdar D. almost 7 years
    Thank you very much my friend, it worked. Did you send a pull request for that bug fix?
  • maudulus
    maudulus almost 7 years
    This worked - thank you! Do you think uninstalling/re-installing ios-sim would work too?
  • Hirbod
    Hirbod almost 7 years
    Thank you very much your last tip worked for me using with OnsenUI / Monaca
  • Dallas Clark
    Dallas Clark almost 7 years
    I can confirm, the following worked for me: $ cd platforms/ios/cordova/node_modules/ $ sudo npm install ios-sim@latest
  • Hirbod
    Hirbod almost 7 years
    See also my answer. Shazron Abdullah also posted that this has been fixed in the next release. More details how to add an "interims" platform to fix this problem github.com/phonegap/ios-sim/pull/213
  • Shaun Cheng
    Shaun Cheng almost 7 years
    Thanks for your great solution.
  • Petroff
    Petroff over 6 years
    @JedatKinports why with sudo? For me works without sudo like a charm.
  • Tadej
    Tadej over 6 years
    @Petroff don't remember. If it works without sudo, fine. :)
  • Segers-Ian
    Segers-Ian over 6 years
    I am sorry, but a sudo for a npm install for a local package. Please don't spread such tips.
  • Tadej
    Tadej over 6 years
    I thought that i had the -g flag. Added it. But even then it's not needed, both should work, what ever you like.
  • chintan adatiya
    chintan adatiya over 6 years
    ios-sim need to be globally installed, sorry for late reply