106 lines
3.0 KiB
Markdown
106 lines
3.0 KiB
Markdown
|
## tips and tricks
|
||
|
|
||
|
### seeing output of macros
|
||
|
|
||
|
```nimrod=
|
||
|
import macros
|
||
|
|
||
|
expandmacros:
|
||
|
#code
|
||
|
```
|
||
|
|
||
|
then during compilation it will display what the expanded code looks like
|
||
|
|
||
|
### Getting notified for QML properties changing
|
||
|
|
||
|
Each QML property has an `onChange` attached to it automatically.
|
||
|
|
||
|
For example, if you a property named `name`, it will have an `onNameChanged`. It follows the pattern: `on` + Property + `Change`.
|
||
|
|
||
|
Eg:
|
||
|
```
|
||
|
property int index: 0
|
||
|
|
||
|
onIndexChanged: {
|
||
|
console.log('Index changed', index)
|
||
|
}
|
||
|
```
|
||
|
|
||
|
## Async
|
||
|
```nimrod
|
||
|
import chronos
|
||
|
|
||
|
proc someFunction*(someParameter:int): Future[string] {.async.}=
|
||
|
result = "Something"
|
||
|
|
||
|
|
||
|
var myResult = waitFor someFunction(1)
|
||
|
|
||
|
# If inside some async function
|
||
|
var myResult = await someFunction(6464435)
|
||
|
|
||
|
# to discard the result,
|
||
|
asyncCheck someFunction(2332)
|
||
|
|
||
|
```
|
||
|
|
||
|
`nim-chronos` API is compatible with https://nim-lang.org/docs/asyncdispatch.html so this page can be used to complement nim-chronos lack of documentation. ([Wiki](https://github.com/status-im/nim-chronos/wiki/AsyncDispatch-comparison))
|
||
|
|
||
|
## Updating data on a QAbstractListModel
|
||
|
While adding/removing values from a list is easy, updating the values of a list requires some extra manipulation:
|
||
|
```
|
||
|
proc updateRecord(idx: int, newValue: string) =
|
||
|
self.myList[idx] = newValue;
|
||
|
var topLeft = self.createIndex(idx,0,nil)
|
||
|
var bottomRight = self.createIndex(idx,0,nil)
|
||
|
self.dataChanged(topLeft, bottomRight, @[RoleNames.SomeRole.int, RoleNames.AnotherRole.int, RoleNames.SomeOtherRole.int])
|
||
|
```
|
||
|
|
||
|
If more than one record is being updated at once, change the `topLeft`'s and `bottomRight`'s `self.createIndex` first parameter to indicate the initial row number and the final row number that were affected.
|
||
|
|
||
|
To refresh the whole table, I think you can use `0` as the first parameter for `createIndex` for both `topLeft` and `bottomRight`.
|
||
|
|
||
|
The final attribute of `dataChanged` is a non-empty sequence of RoleNames containing the attributes that were updated
|
||
|
|
||
|
## Error Handling and Custom Errors
|
||
|
|
||
|
### Raising Custom errors
|
||
|
|
||
|
```nim
|
||
|
type
|
||
|
CustomError* = object of Exception # CatchableError/Defect
|
||
|
|
||
|
try:
|
||
|
raise newException(CustomError, "Some error message")
|
||
|
except CustomError as e:
|
||
|
echo e.msg
|
||
|
```
|
||
|
|
||
|
### Raising Custom Errors with custom data (and parent Error)
|
||
|
|
||
|
```nim
|
||
|
type
|
||
|
CustomError* = object of Exception
|
||
|
customField*: string
|
||
|
|
||
|
type CustomErrorRef = ref CustomError
|
||
|
|
||
|
try:
|
||
|
raise CustomErrorRef(msg: "Some error message", customField: "Some custom error data", parent: (ref ValueError)(msg: "foo bar"))
|
||
|
except CustomError as e:
|
||
|
echo e.msg & ": " & e.customField
|
||
|
echo "Original: " & e.parent.msg
|
||
|
```
|
||
|
|
||
|
### Implementing custom Error helpers with default values
|
||
|
|
||
|
```nim
|
||
|
type
|
||
|
CustomError* = object of Exception
|
||
|
customField*: string
|
||
|
|
||
|
type CustomErrorRef = ref CustomError
|
||
|
|
||
|
proc newCustomError*(customData: string): CustomErrorRef =
|
||
|
result = CustomErrorRef(msg: "This is some custom error message", customField: customData, parent: (ref ValueError)(msg: "Value error"))
|
||
|
```
|