# SelectorFor

### Single Field Selector

`SelectorFor` allows to select specific fields in a object and trigger a callback when those fields change (by reference or by value).&#x20;

`SelectorFor` is used together with [BlocSelector](/compose-bloc/bloc-documentation/blocs-and-compose-overview/blocselector.md) , to choose the data from a [Bloc ](/compose-bloc/bloc-documentation/bloc-and-cubit-overview/bloc.md)state that we want to use as state that should trigger recomposition.

More precisely, with `SelectorFor` we can build an `AbstractSelector` object that we can pass as argument to `BlocSelector`. Let's see some examples on how this is done.

Let us assume that the state object from which we want to select data is the following:

```kotlin
class StateABC(val a:Int, val b:Int, val c:Int)
```

For example if we are interested in the `a` field, we can write:

```kotlin
//sel_a is of type AbstractSelector<StateABC>
val sel_a = SelectorFor<StateABC>.withSingleField { a }
```

### Selector for Multiple Fields

With a selector we can also check for changes of multiple fields in an object and combine them in a computed value:

```kotlin
//sel_sum_ab is of type AbstractSelector<StateABC>
val sel_sum_ab =
 SelectorFor<StateABC>
    .withField{a}
    .withField{b}
    .compute {a,b -> a+b}
```

`sel_sum_ab` will keep track when the class field `a` and `b` change and automatically recompute their sum and trigger a state change with the value of the sum.

### Equality Check by Reference or by Value

Let's say now that we the following state object:

```kotlin
data class StateABCStrings(val astr:String="", val bstr:String="", val cstr:String="")
```

Again, if we are interested in the `a` field, we can write

```kotlin
//sel_astr  is of type AbstractSelector<StateABCStrings>
val sel_astr = SelectorFor<StateABCStrings>.withSingleField { astr }
```

But what happens when the state change? The selector `sel_astr` we have built is able to identify changes to the `astr` field. By default changes are checked ***by reference .*** In other words if we have the two states:

```kotlin
val state1 = StateABCStrings(astr="aa")
val state2 = StateAbcStrings.copy(astr="a"+a")
```

the two states `state1` and `state2` are considered different by the selector `sel_astr` . This is not always the desired behaviour. Sometimes we want to check if the "value", not the "reference" of a field has changed. If this is what we want then we must use `withSingleFieldByValue`

```kotlin
//sel_astr_by_val  is of type AbstractSelector<StateABCStrings>
val sel_astr_by_val = SelectorFor<StateABCStrings>.withSingleFieldByValue { astr }
```

With this definition of the selector `state1` and `state2` above will be considered equal and will not considered a state change.

We can choose equality check by value also for selectors based on multiple fields:

```kotlin
//sel_sum_ab_str  is of type AbstractSelector<StateABCStrings>
val sel_sum_ab_str =
 SelectorFor<StateABCStrings>
    .withFieldByValue{ astr }
    .withFieldByValue{ bstr }
    .compute {astr, bstr  -> astr+bstr }
```

### Building multiple selectors for the same state

`SelectorFor` is can be used to build multiple `AbstractSelector`  ***at once**,* as we can see in the following example:

```kotlin
val sel = SelectorFor<StateABC>

val sel_a = sel.withSingleField { a } //this is an AbstractSelector<StateABC>
val sel_b = sel.withSingleField { b } //this is an AbstractSelector<StateABC>
val sel_for_a = sel.withField { a } //this is still a BUILDER for an AbstractSelector
val sel_sum_ab = sel_for_a.withField { b }.compute {a,b->a+b} //this is an AbstractSelector<StateABC>
val sel_sum_ac = sel_for_a.withField { c }.compute {a,c->a+c}  //this is an AbstractSelector<StateABC>
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://beyondeye.gitbook.io/compose-bloc/bloc-documentation/blocs-and-compose-overview/selectorfor.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
