I'd like to lead off with, this isn't the async issues that other people have posted about where their pushes aren't doing anything. Here is my code
function createHolderPosition(holder: Holder, position: Position): void {
if(holder.positions == null){
holder.positions = []
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const length = holder.positions!.push(position.id);
log.info("new length {}", [length.toString()])
log.info("POsition id to add {}", [position.id])
log.info("POsition {}", [holder.positions!.toString()])
log.info("POsition {}", [holder.positions![0]])
And here is the output of these log statements
new length 1
POsition id to add 123
POsition
Mapping aborted at ~lib/array.ts, line 106, column 42, with message: Index out of range
So. The push statement returns 1, indicating that the array is now length 1 (as you'd expect). The position.id that we pushed definitely wasn't null. But when we try to print the array, we get nothing? And we get an index out of range error when we try to access the element we just thought we pushed
--EDIT I think I figured it out Here are the the definitions of Holder and Position, in my graphql schema.
type Position @entity {
# Wallet address - Position (0x0000-xStella)
id: ID!
# xStella, STELLA-GLMR, STELLA-USDC, Vaults, TriPool
type: String!
# Amount of Stella
amount: BigInt!
# Time
timestamp: BigInt!
holder: Holder!
}
type Holder @entity {
# Wallet address
id: ID!
# Holding
stellaHolding: BigInt!
# Timestamp
lastTransaction: BigInt!
positions: [Position!] @derivedFrom(field: "holder")
}
And here is my generated code
get positions(): Array<string> | null {
let value = this.get("positions");
if (!value || value.kind == ValueKind.NULL) {
return null;
} else {
return value.toStringArray();
}
}
So, even though I'm new to typescript, what this looks like to me is that this getPositions function is returning a new instance of the array (contrary to what you might intuitively expect). I was able to actually push to the array by doing the following
function createHolderPosition(holder: Holder, position: Position): void {
if(holder.positions == null){
holder.positions = []
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const newPositions: string[] = holder.positions!
newPositions.push(position.id)
holder.positions = newPositions
If
positionsis only getter you can't assign it asholder.positions = []. It should be a compiler error. Latest AssemblyScript 0.20.16 produce proper error for this case. See playgrundIf
Holderin your example has setter as well, thenvalue.toStringArray()may create and return a new object which doesn't connect tovalueanymore (basically it can't modify internal state ofvalueand can interpret as immutable). Then, much better, refactor your code as:Btw then you won't need exclamation marks in this case