1

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
Steve
  • 4,457
  • 12
  • 48
  • 89

1 Answers1

0

If positions is only getter you can't assign it as holder.positions = []. It should be a compiler error. Latest AssemblyScript 0.20.16 produce proper error for this case. See playgrund

If Holder in your example has setter as well, then value.toStringArray() may create and return a new object which doesn't connect to value anymore (basically it can't modify internal state of value and can interpret as immutable). Then, much better, refactor your code as:

let positions = holder.positions;
if  (positions == null) {
  positions = [];
}
positions.push(position.id)
holder.positions = positions

Btw then you won't need exclamation marks in this case

MaxGraey
  • 351
  • 2
  • 6