# Component Actions, what are they?!

[*In a previous article, we took a look at one of the new property types of components called Functions*](https://sgtcrab64.hashnode.dev/components-lets-make-a-function). Today we're going to look at Actions, which are *eerily* similar to Functions 👻

---

I'll admit that it's taken me longer than I'm willing to admit to get my head around the purpose of actions, the description given by Microsoft it a little... weird.

> This type of property can be called as a function with parameters, and can contain logic that changes state (side effects).

So we can call an action like a function, and pass parameters in. All good. But side effects? What's that?

---

## So, side effects then?

Side Effects in PowerFx seem to have a broad meaning; There are two popular functions that have "Side effects":

**Select()**, and

**Reset()**

Select() will simulate a selection of a control (Generally, any that have an OnSelect() function). Reset() will, well, reset a resettable control.

But also, SubmitForm() hass a Side Effect, rightly, because it affects your Edit Form's datasource, or the record passed in.

Now, the current documentation for Action Properties suggests you can update a datasource, but from what I can ascertain; this isn't currently working. [I've raised an issue on the documentation repo and will update this when I hear back.](https://github.com/MicrosoftDocs/powerapps-docs/issues/4530)

So what we're saying with Actions, is that we can trigger **Side-Effects** within our components of controls within our component. I'll lead by example:

---

## So with that, let's make an Action...

There's a business requirement to track when a crab has graced us with their pincers 🦀. I need to be able to grace our component by either:

* Selecting the button in the component.
    
* By selecting a special button that isn't in our component.
    

This will be fairly straight forward, we have a component configured with a button and label as below:

![No alt text provided for this image](https://media.licdn.com/dms/image/D4E12AQHNhloXvL2mqg/article-inline_image-shrink_1500_2232/0/1688932907441?e=1700092800&v=beta&t=wa1J4WzvYDhAF3AEjX0O_gsWEBr0htNkNuQZ_c_--UU align="center")

The button code isn't much, we're going to increment a variable within the component by 1 with each pinc.. click.

```plaintext
Set(gvClicks, gvClicks + 1)
```

With a label to show the results. And.. as you would expect...

![No alt text provided for this image](https://media.licdn.com/dms/image/D4E12AQG7oNdahAL57Q/article-inline_image-shrink_1500_2232/0/1688933597145?e=1700092800&v=beta&t=malO9fvOpqgnVs1JTK4UCepY1U6ez0lSfGULAtthIHE align="center")

So Action Property Types come in when we want to trigger the **Select()** function of the "Click Me 🦀" button within our component from the App scope.

---

## It's about time we made an Action!

Create a property in the component as follows:

![No alt text provided for this image](https://media.licdn.com/dms/image/D4E12AQFgeweA70np1g/article-inline_image-shrink_1500_2232/0/1688933730647?e=1700092800&v=beta&t=9psv8GaQvNZbRM_d4BlA6D7STV0-xBrL9x2x9FQXScs align="center")

Note: If you can't see the additional property types, you'll need to enable Enhanced Component Properties from the Settings menu, you'll want to ensure you have "Enhanced component properties" from "Settings" &gt; "Upcoming features" enabled.

The code we're going to add is simply going to Select the button:

```plaintext
Select(btn_GracePincer)
```

Next, we'll need to add our component to a screen so we can **Call this Action:**

---

## Call the Action

![No alt text provided for this image](https://media.licdn.com/dms/image/D4E12AQEHvGxzcALaVw/article-inline_image-shrink_1500_2232/0/1688933997406?e=1700092800&v=beta&t=56u5jK5ZnzHJkISNLgCXRZVvaA2ZeG7F0eJ7fTej-iI align="center")

I've added a telepathic button to the app, along with the component itself.

We can use the "Telepath Pincer" button to call the Action in the Component below (in pink, or orange, or a mixture of the two?).

The OnSelect property of the top button should just call the action as follows:

```plaintext
cmpPincer.GracePincer()
```

The result is the code in GracePincer() is triggered, which Selects the "Click Me" button within the component, thus our pincer counter continues to climb.

![No alt text provided for this image](https://media.licdn.com/dms/image/D4E12AQE1BYbvZl3Yog/article-inline_image-shrink_1500_2232/0/1688934457028?e=1700092800&v=beta&t=y-S-gceFMM2Braan9bkx-R63czqP9g8e02db_NbUzWc align="center")

---

## So... why?

Okay, we don't all work with Crabs. But there is a reason Actions exist:

* Components are resettable, but resetting a component resets all controls/variables etc in the components. Actions mean we can specifically target controls/variables etc when doing a reset.
    
* Select() can't be used on components. So actions now give us a way to perform Select()-ish "Side Effect Formula" on components, and we can choose what is/isn't selected.
    
* Once more, you get full access to the Component Scope, so you can add to collections, set variables etc, via the Action. So pass in a record as a parameter, and add it to the components collection! Here's an example below of a component that takes in a staff record (Name, Role and Photo) and adds to a collection within the component:
    

---

## Collections and Records example

We have a property in a component called "Ingest Record", which takes a record as a parameter:

![No alt text provided for this image](https://media.licdn.com/dms/image/D4E12AQHw82ogFZ_IRg/article-inline_image-shrink_1500_2232/0/1688940233778?e=1700092800&v=beta&t=MLVAB_XVkhPsi4Tl-jdowOjXbdA2RNoVwwqj0ElZScU align="left")

The component has a Gallery to display the contents of the collection *colRecords*.

The property above has the following code:

```plaintext
Collect(colRecords, Record)
```

We define the schema of *Record* with:

```plaintext
{ 
    Name: "Mike Gowland",
    Role: "Developer",
    Photo: SampleImage
}
```

And we can now implement the component in an app, and call *IngestRecord,* passing in a record that matches the above schema for the *Record* parameter:

```plaintext
cmpStaff.IngestRecord(
    {
        Name: txtName.Text,
        Role: txtRole.Text,
        Photo: AddMediaButton1.Media
    }
)
```

And the results:

![No alt text provided for this image](https://media.licdn.com/dms/image/D4E12AQHumCA1jhzxRA/article-inline_image-shrink_1500_2232/0/1688940488343?e=1700092800&v=beta&t=hr2bKyxhODc-LEfnPCedmXCxSfNPIKdBr6SuyPbcqno align="left")

Oh, and don't forget, action properties give an output too 😁

```plaintext
If(cmpStaff.IngestRecord(
    {
        Name: txtName.Text,
        Role: txtRole.Text,
        Photo: AddMediaButton1.Media
    }
),Notify("Record added"))
```

---

## **Next Time**

We'll take a look at Events, which are probably already familiar to those who used Behaviour properties in the past.

---

Thanks for reading this article, I'm wondering, what are your use cases for Actions? I'd love to read them in the comments below 👇
