Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using outArgs.getArgs().get(0).getValue().toString(), but get a wrong value #2

Open
shadow-001 opened this issue Jun 10, 2022 · 4 comments

Comments

@shadow-001
Copy link

I use outargs getArgs(). get(0). getValue(). Tostring() gets the result and refers to Querytest. However, the final data obtained is inconsistent with the data recorded in canisters.

QyeryTest:
image

canister response:
image

java result:
image

@rdobrik
Copy link
Contributor

rdobrik commented Jun 10, 2022

Thank you for reporting this issue. Let me check your use case and fix the problem.

@rdobrik
Copy link
Contributor

rdobrik commented Jun 10, 2022

Can you please share with me IDL of the canister you are calling from Java?

@shadow-001
Copy link
Author

export const idlFactory = ({ IDL }) => {

  const CanisterSettings = IDL.Record({
    'controller' : IDL.Opt(IDL.Principal),
    'freezing_threshold' : IDL.Opt(IDL.Nat),
    'controllers' : IDL.Opt(IDL.Vec(IDL.Principal)),
    'memory_allocation' : IDL.Opt(IDL.Nat),
    'compute_allocation' : IDL.Opt(IDL.Nat),
  });
  const CreateCanisterArgs = IDL.Record({
    'cycles' : IDL.Nat64,
    'settings' : CanisterSettings,
  });
  const Result = IDL.Variant({ 'Ok' : IDL.Principal, 'Err' : IDL.Text });

  return IDL.Service({
    'create_canister' : IDL.Func([CreateCanisterArgs], [Result], []),
  });
};
export const init = ({ IDL }) => { return []; };

@rdobrik
Copy link
Contributor

rdobrik commented Jun 11, 2022

Aah, you are returning Variant type, which wraps Principal value. In such case we are wrapping variant elements as a Java map type. So you have to get Ok item from the Map. I added Variant test echoVariant in our ICTest JUnit test (already checked in). It handles Variant Result similar to yours

type Result = {
    #Ok : Principal;
    #Err : Text;
};

So you get value as a Map and then you retrieve Principal value.

byte[] queryOutput = queryResponse.get();
IDLArgs outArgs = IDLArgs.fromBytes(queryOutput);
					
Map<Label, Object> mapResult = outArgs.getArgs().get(0).getValue();
					
if(mapResult.containsKey(Label.createNamedLabel("Ok")))
{
	Principal principalResult = (Principal) mapResult.get(Label.createNamedLabel("Ok"));
	LOG.info(principalResult.toString());
	Assertions.assertEquals(principalValue, principalResult);
}

We also serializing and deserializing IC variants to Java Enum type. You can find the sample in our Internet Identity package.

https://github.com/ic4j/ic4j-internetidentity/blob/master/src/test/java/org/ic4j/internetidentity/test/InternetIdenityTest.java

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants