All Projects → gabrielperales → elm-native-module

gabrielperales / elm-native-module

Licence: other
Example of how to do an Elm native module

Programming Languages

elm
856 projects
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to elm-native-module

react-native-android-wear-demo
Showcase of a two-way communication between React Native and Android Wear apps.
Stars: ✭ 93 (+173.53%)
Mutual labels:  native-module
react-native-ios-modal
A react-native component for displaying a modal on iOS by natively wrapping a react-native view inside a UIViewController and presenting it.
Stars: ✭ 94 (+176.47%)
Mutual labels:  native-module
electron-react-ts-rxdb-realm-sqlite
Demo of Native Databases with Electron and ReactJS. Realm, SQLite and RxDB ( with LevelDB/IndexedDB/InMemory adapters)
Stars: ✭ 27 (-20.59%)
Mutual labels:  native-module
react-native-google-nearby-messages
📲 Communicate with nearby devices using Bluetooth, BLE, WiFi and near-ultrasonic audio. Broadcast and receive small payloads (like strings) using the easy-to-use React Native API!
Stars: ✭ 143 (+320.59%)
Mutual labels:  native-module
ti.moddevguide
Appcelerator Titanium native Module Guide
Stars: ✭ 39 (+14.71%)
Mutual labels:  native-module
ps facetedsearch
PrestaShop module that adds layered navigation filters.
Stars: ✭ 45 (+32.35%)
Mutual labels:  native-module
productcomments
PrestaShop module that allows users to post reviews and rate products.
Stars: ✭ 29 (-14.71%)
Mutual labels:  native-module
react-native-broadcast
React Native bindings for RTMP broadcasting
Stars: ✭ 39 (+14.71%)
Mutual labels:  native-module
gsitemap
This module generates your Google sitemap file
Stars: ✭ 52 (+52.94%)
Mutual labels:  native-module
react-native-tracking-transparency
🕵️ A React Native Library for interacting with the tracking API from iOS 14.
Stars: ✭ 149 (+338.24%)
Mutual labels:  native-module
blockreassurance
Adds an information block aimed at offering helpful information to reassure customers that your store is trustworthy.
Stars: ✭ 15 (-55.88%)
Mutual labels:  native-module
chain-react-bridging
Chain React 2017: Breaking Down React Native Bridging
Stars: ✭ 14 (-58.82%)
Mutual labels:  native-module
react-native-open-notification
www.npmjs.com/package/react-native-open-notification
Stars: ✭ 23 (-32.35%)
Mutual labels:  native-module

Elm native module

This is highly discouraged, and will not be possible in future versions of Elm.

The core Elm libraries need access to JavaScript to expose HTTP in Elm (for example) but this is not a public API. It is not intended for public use. It can change dramatically from release to release. It is not permitted in published packages. And again, in future versions, it will not be accessible.

In summary, it is better to figure out how to structure code such that ports will be a good option. If you cannot achieve what you want after asking around on Slack, the best path may be to circle back around to Elm later when more of the Web Platform is covered to your liking.





What?

This is an example of how to do elm native modules for elm 0.18. It contains a native module with a helloWorld function which receives a name parameter and returns a string with that name appended to the 'Hello ' string and an exclamation at the end.

Why?

There are not too many tutorials about how native modules. One of them is the wiki of take-home but it is not updated for elm 0.17 and up. Also, I have included some tests, so you can learn how to test your own native modules.

How?

Getting Starting

You need to have elm installed, and also elm-test because we are going to write a test for our native module. You can do it with this commands:

$ npm i -g elm
$ npm i -g elm-test

Once you have both installed, we are goint to create a folder and execute elm-test init. That will create two folders, src and tests. Test folder comes with some example elm tests.

.
├── src
└── tests
    ├── Main.elm
    ├── Tests.elm
    └── elm-package.json

You can execute them running elm-test in your command line.

After running elm-test you should see something like this:

first run elm-test

Our next step will be writting our first test. To do that we have to replace the content of tests/Tests.elm with this content:

module Tests exposing (..)

import Test exposing (..)
import Expect

import NativeModule exposing (helloWorld)

all : Test
all =
    describe "Native module test suite"
        [ describe "helloWorld"
            [ test "empty string" <|
                \() ->
                    Expect.equal (helloWorld "") "Hello !"
            ]
        ]

If we try to run elm-test again, an error will show up telling us that the module NativeModule we are trying to import can't be found. That is right... we haven't done it yet!.

Our next step will be create that module, so we have to create a file called NativeModule.elm inside the src folder. (You can replace NativeModule with something more descriptive in your project).

Inside it, we are going write the lines under this:

module NativeModule exposing (helloWorld)

helloWorld: String -> String
helloWorld =
  Native.NativeModule.helloWorld

There, we are creating a module called NativeModule which is exposing a function called helloWorld. That function annotation is telling us that it is going to receive a string as a parameter and it is going to return another string. Also we are telling that its implementation is going to be Native.NativeModule.helloWorld. What is going to happend if we try to run our tests again?

If we do it, we will see an error in the terminal:

ReferenceError: _user$project$Native_NativeModule is not defined

What does it mean? Elm compiler is telling us that it is trying to find a native module with the name _user$project$Native_NativeModule, that it because in Elm all the packages are scoped by the username and the project name where they are stored in github. If you change the content of the line repository in tests/elm-package.json for something like https://github.com/gabrielperales/elm-native-module.git and then you run elm-test again you will see that now it is trying to find _gabrielperales$elm_native_module$Native_NativeModule. Let's going to implement that module!

Create a new file in src/Native called NativeModule.js and write this code there:

var _gabrielperales$elm_native_module$Native_NativeModule = function(){
  function helloWorld(name){
    return "Hello " + name + "!";
  }

  return {
    helloWorld: helloWorld
  };
}();

(In your project, you can again rename NativeModule.js to something more appropriate, but the parent directory must be Native for it to be found, at least with current Elm).

You will also need to modify your elm-package.json file to include the directive:

{
    ...
    "native-modules": true,
    ...
}

The last thing we have to do is import that native module inside our elm module. You only have to type import Native.NativeModule under you module definition.

Your module should end looking like this:

module NativeModule exposing (helloWorld)
{-| Creating our first native module

# helloWorld function
@docs helloWorld
-}
import Native.NativeModule

{-| This function will return 'Hello ' prepended to the name you are passing to it
-}
helloWorld : String -> String
helloWorld =
    Native.NativeModule.helloWorld

Finally, we can run our first test again and it should pass.

Now we can write a new test to check that every thing works as we were expecting.

, test "name" <|
    \() ->
        Expect.equal (helloWorld "Gabi") "Hello Gabi!"

If everything is ok, it also should pass that test.

For functions of more than one argument, you can wrap the function with FN, where N is the number of arguments. This turns the function into one that can be called using Elm conventions, while still being written as a normal Javascript function. For example:

var _gabrielperales$elm_native_module$Native_NativeModule = function(){
  function sum(one, two){
    return one + two;
  }

  return {
    sum: F2(sum)
  };
}();

The functions F2, F3... F9 are provided by Elm.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].