---
# System prepended metadata

title: "\U0001F477‍♂️ Classes and Shared Objects"

---

# 👷‍♂️ Classes and Shared Objects 

## 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)

---

## Classes

### Task 1 

Export from `ChartModule` an empty native class the is called `Class`.

:::spoiler :robot_face: Android 

:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt`

```kotlin
Class("Class") {
  
}
```

:::
 
:::spoiler :apple: iOS

:open_file_folder: File `ios/ChartsModule.swift`

```swift
Class("Class") {
  
}
```

:::


<br />

📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/7e91e3e291eec8019af6b4bc9343c0ace588f9c5)

---

### Task 2 

Add a native constructor to the exported class. This constructor should have the option to receive an integer parameter and also set the property (named `property`). If no value is provided, the default value of `10` should be used.

:::spoiler :robot_face: Android 

:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt`

```kotlin
Constructor { self: JavaScriptObject, value: Int? ->
  self.setProperty("property", value ?: 10)
}
```

:::
 
:::spoiler :apple: iOS

:open_file_folder: File `ios/ChartsModule.swift`


```swift
Constructor { (this: JavaScriptObject, value: Int?) in
  this.setProperty("property", value: value ?? 10)
}
```

:::

<br />

📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/f1b3120006a917079817ea38d4d097df859255a6)

---

### Task 3

Add an async function named `modifyProperty` that will multiply the value of the previously set property by itself. 

:::spoiler :robot_face: Android 

:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt`

```kotlin
Function("modifyProperty") { self: JavaScriptObject ->
  val p = self.getProperty("property").getInt()
  self.setProperty("property", p * p)
}
```

:::
 
:::spoiler :apple: iOS

:open_file_folder: File `ios/ChartsModule.swift`


```swift
Function("modifyProperty") { (this: JavaScriptObject) in
  let p = this.getProperty("property").getInt()
  this.setProperty("property", value: p * p)
}
```

:::

<br />

📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/ce81903864c6b8866d8df905f6dad24d8aa8bd55)

---

### Task 4

Create a duplicate of the `modifyProperty` function and make it asynchronous.

:::spoiler :robot_face: Android 

:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt`

```kotlin
AsyncFunction("modifyPropertyAsync") { self: JavaScriptObject, promise: Promise ->
  appContext.executeOnJavaScriptThread {
    val p = self.getProperty("property").getInt()
    self.setProperty("property", p * p)
    promise.resolve(null)
  }
}
```

:::
 
:::spoiler :apple: iOS

:open_file_folder: File `ios/ChartsModule.swift`


```swift
AsyncFunction("modifyPropertyAsync") { (this: JavaScriptObject, promise: Promise) in
  guard let context = appContext else {
    throw Exceptions.AppContextLost()
  }

  context.executeOnJavaScriptThread {
    let p = this.getProperty("property").getInt()
    this.setProperty("property", value: p * p)
    promise.resolve()
  }
}
```

:::

<br />

📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/c89c325700d85eb2546b3917d02c0deebdf60460)

---


### Task 5 

Add a function that returns an anonymous object. This object should contain a function called `calculate`, which receives three integers and returns their sum.

:::spoiler :robot_face: Android 

:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt`

```kotlin
Function("createAnonymousObject") {
  return@Function Object {
    Function("calculate") { a: Int, b: Int, c: Int ->
      a + b + c
    }
  }
}
```

:::
 
:::spoiler :apple: iOS

:open_file_folder: File `ios/ChartsModule.swift`

```swift
Function("createAnonymousObject") {
  Object {
    Function("calculate") { (a: Int, b: Int, c: Int) in
      a + b + c
    }
  }
}
```

:::


<br />

📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/89c4e4f09065034c82730f78eb427adad44ff372)

---

## Shared Objects

### Task 6

Create a shared object that represents a list of integers. This object should allow for the addition and retrieval of elements, as well as checking its size.

:::spoiler :robot_face: Android 

:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt`

```kotlin
class SharedList<T> : SharedObject() {
  private val data = mutableListOf<T>()

  val size: Int
    get() = data.size

  fun add(newElement: T) {
    data.add(newElement)
  }

  operator fun get(index: Int): T {
    return data[index]
  }
}
```

:::
 
:::spoiler :apple: iOS

:open_file_folder: File `ios/ChartsModule.swift`

```swift
class SharedList : SharedObject {
  private var data: [Int] = []

  var size: Int {
    data.count
  }

  func add(_ newElement: Int) {
    data.append(newElement)
  }

  subscript(index: Int) -> Int {
    get {
      return data[index]
    }
  }
}
```

:::

<br />

📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/8d5d3cdebbb1affbf812e4fd853cc41f3eadc8f1)

---

### Task 7 

Export a shared list within a native class. The exported structure's JavaScript representation must follow an interface:
```typescript
interface SharedList {
  new (): SharedList;

  readonly add: (newValue: number) => void;
  readonly get: (index: number) => number;
  readonly size: () => number;

  readonly addAsync: (newValue: number) => Promise<void>;
  readonly getAsync: (index: number) => Promise<number>;
  readonly sizeAsync: () => Promise<number>;
}
```


:::spoiler :robot_face: Android 

:open_file_folder: File `android/src/main/java/expo/modules/workshopscharts/ChartsModule.kt`

```kotlin
Class(SharedList::class) {
  Constructor {
    return@Constructor SharedList<Int>()
  }

  Function("add") { sharedObject: SharedList<Int>, newValue: Int ->
    sharedObject.add(newValue)
  }

  Function("get") { sharedObject: SharedList<Int>, index: Int ->
    sharedObject[index]
  }

  Function("size") { sharedObject: SharedList<Int> ->
    sharedObject.size
  }

  AsyncFunction("addAsync") { sharedObject: SharedList<Int>, newValue: Int ->
    sharedObject.add(newValue)
  }

  AsyncFunction("getAsync") { sharedObject: SharedList<Int>, index: Int ->
    sharedObject[index]
  }

  AsyncFunction("sizeAsync") { sharedObject: SharedList<Int> ->
    sharedObject.size
  }
}
```

:::
 
:::spoiler :apple: iOS

:open_file_folder: File `ios/ChartsModule.swift`


```swift
Class(SharedList.self) {
  Constructor {
    return SharedList()
  }

  Function("add") { (sharedObject: SharedList, newValue: Int) in
    sharedObject.add(newValue)
  }

  Function("get") { (sharedObject: SharedList, index: Int) in
    sharedObject[index]
  }

  Function("size") { (sharedObject: SharedList) in
    sharedObject.size
  }

  AsyncFunction("addAsync") { (sharedObject: SharedList, newValue: Int) in
    sharedObject.add(newValue)
  }

  AsyncFunction("getAsync") { (sharedObject: SharedList, index: Int) in
    sharedObject[index]
  }

  AsyncFunction("sizeAsync") { (sharedObject: SharedList) in
    sharedObject.size
  }
}
```

:::

<br />

📝 Full changelog: [open GitHub Commit](https://github.com/software-mansion-labs/appjs-2023-workshop-expo-modules/commit/bb42e64a68f83bc91c3876c796af548f8376d164)

---

## [📊 Views and shared object](/IgHyIAHQQPCbeBD74Ri4BA)