0

I have an API that returns a JSON object as such:

[
  {
    "id": 2435,
    "name": "First Last",
    "email": "xxx@gmail.com",
    "gender": "male",
    "status": "inactive"
  },
...

And I'm attempting to populate the response into a struct list variable (users) using Chainlink any API.

Please find below the contract code :

    pragma solidity ^0.8.7;
    import '@chainlink/contracts/src/v0.8/ChainlinkClient.sol';
    import '@chainlink/contracts/src/v0.8/ConfirmedOwner.sol';

    contract FetchFromArray is ChainlinkClient, ConfirmedOwner {
    using Chainlink for Chainlink.Request;

    
    string public jsonData;
    bytes32 private jobId;
    uint256 private fee;
    User[] public users;    

    struct User{
      uint256 id;
      uint256 name;
      uint256 email;
      uint256 gender;
      uint256 status;
    }

    event GetUsersData(bytes32 indexed requestId, string jsonData);


    /**
     * @notice Initialize the link token and target oracle
     *
     *
     */
    constructor() ConfirmedOwner(msg.sender) {
        setChainlinkToken(0x326C977E6efc84E512bB9C30f76E30c160eD06FB);
        setChainlinkOracle(0xCC79157eb46F5624204f47AB42b3906cAA40eaB7);
        jobId = '7d80a6386ef543a3abb52817f6707e3b';
        fee = (1 * LINK_DIVISIBILITY) / 10; // 0,1 * 10**18 (Varies by network and job)
    }

    /**
     * Create a Chainlink request to retrieve API response
     */
    function getUser() public returns (bytes32 requestId){
        Chainlink.Request memory req = buildChainlinkRequest(jobId, address(this), this.fulfill.selector);

        // Set the URL to perform the GET request on
        req.add('get', 'https://gorest.co.in/public/v2/users');
        req.add('path', '$');
        // Sends the request
        return sendChainlinkRequest(req, fee);
    }

     /**
     * Receive the response in the form of string
     */
    function fulfill(bytes32 _requestId, string memory _jsonData) public recordChainlinkFulfillment(_requestId) {
        emit GetUsersData(_requestId,_jsonData);
        jsonData = _jsonData;
        //  users = TO DO popoluate users list
    }

     /**
     * Allow withdraw of Link tokens from the contract
     */
    function withdrawLink() public onlyOwner {
        LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress());
        require(link.transfer(msg.sender, link.balanceOf(address(this))), 'Unable to transfer');
    }

    }

How do I add my json object to a struct?

Questions :

1 - Which jsonpath expression to use to retrieve the full json response of the api ? I tried req.add('path', '$') and req.add('path', '*'), but both didn't return the json.

2 - Once the full json is retrieved and stored in jsonData variable, how to parse it and insert the result in "User[] public users" variable ?

Patrick Collins
  • 5,621
  • 3
  • 26
  • 64
aminedev
  • 323
  • 3
  • 9
  • 22
  • What's the error you're getting? This isn't enough info currently to go off of. – Patrick Collins Oct 03 '22 at 13:59
  • Hi @PatrickCollins, thanks for your feedback, i updated the post and added the questions. I'm not getting any error, but I'm not able to retrieve the full json response using jsonpath expression. – aminedev Oct 03 '22 at 21:35
  • That would be a lot of gas... You'd have to convert the data from a json object to a bytes object and then convert it from bytes into your struct... I think a better way would be to use a multi-variable response with just the exact data that you want. https://docs.chain.link/docs/any-api/get-request/examples/multi-variable-responses/ – Patrick Collins Oct 04 '22 at 01:33
  • And if you really want all the data, you could use multi-variable response to unpack the data into your struct (again, I don't recommend this as it'll cost a lot of gas) https://docs.chain.link/docs/any-api/get-request/examples/multi-variable-responses/ – Patrick Collins Oct 04 '22 at 01:33

0 Answers0