# ⚙️ Native Module
### Navigation
- [🏡 Native modules made easy with Expo](/gYH9xz-oR2ai0Yih8if50w)
- [👶 First Steps](/ANE6NSUlTSimTIrN-gMsBw)
- [👉 ⚙️ Native Module](/mAIt0ctDTvSL5xV4uE9nWQ)
- [📈 Passing data to view](/_gWWp8uoQwGkqKcEyfk8Tg)
- [📚 View Props](/96IjlLNDRvydILdkbfaA5A)
- [🔥 View Events](/PQWXYmxLRCebmLfx3Fh_gg)
- [🏞️ View Functions](/DcjStCFdT6euzWqnJqCL6w)
- [👷♂️ Classes and Shared Objects](/__42gVw8RqiIgfSbVseIvw)
- [📊 Views and shared object](/IgHyIAHQQPCbeBD74Ri4BA)
---
### Task 1
Export from the `ChartModule` a sync `add` function that sums two integers.
:::spoiler :robot_face: Android
:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt`
```kotlin
Function("add") { a: Int, b: Int ->
return@Function a + b
}
```
:::
:::spoiler :apple: iOS
:open_file_folder: File `ios/ChartsModule.swift`
```swift
Function("add") { (a: Int, b: Int) in
return a + b
}
```
:::
<br />
📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/a06f2111ac03e5c79cacde9f277b8e9ec2745381)
---
### Task 2
Export from the `ChartModule` an async `addAsync` function that sums two integers.
:::spoiler :robot_face: Android
:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt`
```kotlin
AsyncFunction("addAsync") { a: Int, b: Int ->
return@AsyncFunction a + b
}
```
:::
:::spoiler :apple: iOS
:open_file_folder: File `ios/ChartsModule.swift`
```swift
AsyncFunction("addAsync") { (a: Int, b: Int) in
return a + b
}
```
:::
<br />
📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/d22d184f4ebcec4bc538d1d9819bd7b4ca0ad36c)
---
### Task 3
Export a sync function called `calculateAverage`. This function should receive an array of doubles and calculate their average value.
:::spoiler :robot_face: Android
:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt`
```kotlin
Function("calculateAverage") { data: List<Double> ->
return@Function data.average()
}
```
:::
:::spoiler :apple: iOS
:open_file_folder: File `ios/ChartsModule.swift`
```swift
Function("calculateAverage") { (data: [Double]) in
return data.reduce(0.0, +) / Double(data.count)
}
```
:::
<br />
📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/d008477527a65d50e0ca1a4c1f25bead7a6043a8)
---
### Task 4
Export an asynchronous function named `generateDataAsync`, which takes in a single integer - `size` and outputs an array containing numbers ranging from `0` to `size-1`.
:::spoiler :robot_face: Android
:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt`
```kotlin
AsyncFunction("generateDataAsync") { size: Int ->
return@AsyncFunction IntArray(size) { it }
}
```
:::
:::spoiler :apple: iOS
:open_file_folder: File `ios/ChartsModule.swift`
```swift
AsyncFunction("generateDataAsync") { (size: Int) -> [Int] in
var result: [Int] = []
for i in 0..<size {
result.append(i)
}
return result
}
```
:::
<br />
📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/0cc15b384ce2232a29591ecdf5aef647fe9b2fa2)
---
### Task 5
Adjust the previous example to throw a custom coded exception if the size given is less than `0`.
:::spoiler :robot_face: Android
:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt`
```kotlin
class InvalidSizeException : CodedException(
message = "Provided size was invalid"
)
```
```kotlin
AsyncFunction("generateDataAsync") { size: Int ->
if (size < 0) {
throw InvalidSizeException()
}
return@AsyncFunction IntArray(size) { it }
}
```
:::
:::spoiler :apple: iOS
:open_file_folder: File `ios/ChartsModule.swift`
```swift
internal class InvalidSizeException : Exception {
override var reason: String {
"Provided size was invalid"
}
}
```
```swift
AsyncFunction("generateDataAsync") { (size: Int) -> [Int] in
if size < 0 {
throw InvalidSizeException()
}
var result: [Int] = []
for i in 0..<size {
result.append(i)
}
return result
}
```
:::
<br />
📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/03b488e7fe77f9a97620977c9bd6632433b8a966)
---
### Task 6
Export a `VERY_IMPORTANT_CONSTANT` constant equal to `2`.
:::spoiler :robot_face: Android
:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt`
```kotlin
Constants(
"VERY_IMPORTANT_CONSTANT" to 2
)
```
:::
:::spoiler :apple: iOS
:open_file_folder: File `ios/ChartsModule.swift`
```swift
Constants([
"VERY_IMPORTANT_CONSTANT": 2
])
```
:::
<br />
📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/728e02ec297e2d08ace1797243537510688823c4)
---
### Task 7
Export a synchronous `typeOf` function that returns type of the provided argument.
> Use `JavaScriptValue` class as a function parameter.
:::spoiler :robot_face: Android
:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt`
```kotlin
Function("typeOf") { value: JavaScriptValue ->
return@Function value.kind()
}
```
:::
:::spoiler :apple: iOS
:open_file_folder: File `ios/ChartsModule.swift`
```swift
Function("typeOf") { (value: JavaScriptValue) in
return value.kind.rawValue
}
```
:::
<br />
📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/48eb3d10656a87041e62ac68798230457f62fb3d)
---
### Task 8
Export a synchronous `modifyJSObject` function that will alter a provided `JavaScriptObject` by adding a new property called `expo` with the value of `is awesome`.
:::spoiler :robot_face: Android
:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt`
```kotlin
Function("modifyJSObject") { jsObject: JavaScriptObject ->
jsObject.setProperty("expo", "is awesome")
}
```
:::
:::spoiler :apple: iOS
:open_file_folder: File `ios/ChartsModule.swift`
```swift
Function("modifyJSObject") { (jsObject: JavaScriptObject) in
jsObject.setProperty("expo", value: "is awesome")
}
```
:::
<br />
📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/b20b22677b3b4843537496cd77dc8f24db05b0dd)
---
### Task 9
Export a sync `callJSFunction` function that operates synchronously. This function should receive a `JavaScriptFunction<Double>` and use it to perform calculations with `100` and `200` as arguments.
:::spoiler :robot_face: Android
:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt`
```kotlin
Function("callJSFunction") { jsFunction: JavaScriptFunction<Double> ->
return@Function jsFunction(100, 200)
}
```
:::
:::spoiler :apple: iOS
:open_file_folder: File `ios/ChartsModule.swift`
```swift
Function("callJSFunction") { (jsFunction: JavaScriptFunction<Double>) in
return try jsFunction.call(100, 200)
}
```
:::
<br />
📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/21cf6d1cb74a7560b3e99388f19828c87dfe808f)
---
### Task 10
Export an async `objectSummary` function that summaries the provided object by calling `toString` (in Kotlin) or `description` (in Swift).
> Try using `Map<String, Any>`/`[String: Any]` instead of the `JavaScriptObject` class.
:::spoiler :robot_face: Android
:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt`
```kotlin
AsyncFunction("objectSummary") { jsObject: Map<String, Any> ->
return@AsyncFunction jsObject.toString()
}
```
:::
:::spoiler :apple: iOS
:open_file_folder: File `ios/ChartsModule.swift`
```swift
AsyncFunction("objectSummary") { (jsObject: [String: Any]) in
return jsObject.description
}
```
:::
<br />
📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/ec5e12450590ce35b40db66361907659df32f647)
---
### Task 11
Export a module's event named `onNewData` along with its corresponding sync function (`sendOnNewDataEvent`) that will trigger it. The event payload should be equal to `{ value: 123 }`.
:::spoiler :robot_face: Android
:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt`
```kotlin
Events("onNewData")
AsyncFunction("sendOnNewDataEvent") {
sendEvent("onNewData", mapOf(
"value" to 123,
))
}
```
:::
:::spoiler :apple: iOS
:open_file_folder: File `ios/ChartsModule.swift`
```swift
Events("onNewData")
AsyncFunction("sendOnNewDataEvent") {
sendEvent("onNewData", [
"value": 123,
])
}
```
:::
<br />
📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/282045b4e03907744668bf8d4c7942163bb42ad1)
---
### Task 12
Create a custom `Record` called `Point` representing an `x` and `y` coordinates. Then export a sync function `calculateDistance` which will calculate an distance between two points.
> $$
distance = \sqrt{(p1.y - p2.y)^2 + (p1.x - p2.x)^2}
$$
:::spoiler :robot_face: Android
:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt`
```kotlin
data class Point(
@Field
@Required
val x: Double,
@Field
@Required
val y: Double
) : Record
```
```kotlin
Function("calculateDistance") { p1: Point, p2: Point ->
sqrt((p1.y - p2.y) * (p1.y - p2.y) + (p1.x - p2.x) * (p1.x - p2.x))
}
```
:::
:::spoiler :apple: iOS
:open_file_folder: File `ios/ChartsModule.swift`
```swift
internal struct Point: Record {
@Field
var x: Double
@Field
var y: Double
}
```
```swift
Function("calculateDistance") { (p1: Point, p2: Point) in
return sqrt((p1.y - p2.y) * (p1.y - p2.y) + (p1.x - p2.x) * (p1.x - p2.x))
}
```
:::
<br />
📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/48fec3f15c32e8f7060b3b26222666573801e9c7)
---
### Task 13
Create a property that includes a getter and setter to store a Double value. The setter should automatically square any value that is provided.
:::spoiler :robot_face: Android
:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt`
```kotlin
var x = -1.0
// ...
Property("x")
.get { x }
.set { newValue: Double -> x = newValue * newValue }
```
:::
:::spoiler :apple: iOS
:open_file_folder: File `ios/ChartsModule.swift`
```swift
var x = -1.0
// ...
Property("x")
.get { self.x }
.set { (newValue: Double) in self.x = newValue * newValue }
```
:::
<br />
📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/e333a71de151bcbffb672e3d7318b0724249b589)
---
### [📈 Passing data to view](/_gWWp8uoQwGkqKcEyfk8Tg)