+ Start a Discussion
Kamil MieczakowskiKamil Mieczakowski 

parsing json de

I am attempting to parse MatterMark's API, but I am planning to do so selectively, picking only the value pairs that are relevant. The example JSON response is available to be viewed in MatterMark's documentation (here).

Here's my Wrapper:
 
public class MMarkWrapper {
    public class mmark_company_profile {
        public string name {get;set;}
        public string description {get;set;}
        public string employees {get;set;}
        public string employees_6_months_ago {get;set;}
        public string last_funding_amount {get;set;}
        public string last_funding_date {get;set;}
        public string country {get;set;}
        public string total_funding {get;set;}
        public string acquired_by {get;set;}
        public List<mmark_funding_round> mmark_funding_rounds {get;set;}
        
    }
    public class mmark_funding_round {
        public string amount {get;set;}
        public string transaction_currency {get;set;}
        public string series {get;set;}
        public string funding_date {get;set;}
        public string investors {get;set;}
        
    }
    
    public List<mmark_company_profile> mmark_company_profile_list {get; set;}

}

And the Parser:
 
public class MMarkParser {
    public MMarkWrapper wrapper {
        get;
        set;
    }
    
    public void parse() {
        
        //request class
        HTTPRequest request = new HTTPRequest();
        request.setEndpoint(Label.MatterMarkAPI+'/domains/'+ 'marketinvoice.com' +'/companies?key=' +'c878f447941828d91d53ffbebae068cdb7624fb257cca98e2672e8148e039c1c');  
        request.setMethod('GET');
        
        //response class
        HTTP h = new HTTP();
        HTTPResponse response = h.send(request); 
        
        
        wrapper = (MMarkWrapper) JSON.deserialize(response.getBody(), MMarkWrapper.class);
        System.debug(wrapper);
        
    }
    
}

I am trying to get it displayed on this page, but all I am getting is a blank page...
 
<apex:page controller="MMarkParser">
    <apex:form >
        <apex:pageBlock title="MMarkParserResponse">
            <apex:pageBlockButtons >
                <apex:commandButton value="submit" action="{!parse}" reRender="mmark_company_profile"/>
            </apex:pageBlockButtons>
            <apex:pageBlockSection id="mmark_company_profile" columns="1">
                <apex:repeat value="{!wrapper.mmark_company_profile_list}" var="mmark_company_profile">
                    <apex:pageBlockSection columns="2">
                        <apex:facet name="header">Company {!mmark_company_profile.name}</apex:facet>
                        <apex:pageBlockSectionItem >
                            <apex:outputLabel value="Description" for="description" />
                            <apex:outputText value="{!mmark_company_profile.description}" id="description" />
                        </apex:pageBlockSectionItem>
                        <apex:pageBlockSectionItem >
                            <apex:outputLabel value="Employees" for="employees" />
                            <apex:outputText value="{!mmark_company_profile.employees}" id="employees" />
                        </apex:pageBlockSectionItem>
                    </apex:pageBlockSection>
                    <apex:pageBlockSection columns="1">
                        <apex:facet name="header">Funding {!mmark_company_profile.name} Series</apex:facet>
                        <apex:pageBlockTable value="{!mmark_company_profile.mmark_funding_rounds}" var="item" id="mmark_funding_rounds">
                            <apex:column value="{!item.amount}" headerValue="Amount" />
                            <apex:column value="{!item.transaction_currency}" headerValue="Transaction Currency" />
                            <apex:column value="{!item.series}" headerValue="Series" />
                            <apex:column value="{!item.funding_date}" headerValue="Funding Date" />
                        </apex:pageBlockTable>
                    </apex:pageBlockSection>
                </apex:repeat>
            </apex:pageBlockSection>
        </apex:pageBlock> 
    </apex:form>
</apex:page>

I've been trying to debug it with no success, any ideas why this may be not working?
Best Answer chosen by Kamil Mieczakowski
pconpcon
Ok, so you are getting back the results from the single company call.  The URI is just different than what is mentioned in the documentation.  So you'll want to have the following class for your deserialization.  The naming of the fields is the most important part.  Your company information is mostly correct but the funding is not.
 
public class MMarkMetadata {
    public class Funding {
        public String amount {get; set;}
        public String currency {get; set;}
        public String series {get; set;}
        public String funding_date{get; set;}
        public String news_url {get; set;}
        public String source {get; set;}
        public List<Integer> investor_ids {get; set;}
        public String investors {get; set;}
    }

    public class Company {
        public String name {get; set;}
        public String description {get; set;}
        public String website {get; set;}
        public String mattermark_score {get; set;}
        public String employees {get; set;}
        public String employees_month_ago {get; set;}
        public String employees_6_months_ago {get; set;}
        public String website_uniques {get; set;}
        public String mobile_downloads {get; set;}
        public String stage {get; set;}
        public String total_funding {get; set;}
        public String location {get; set;}
        public String city {get; set;}
        public String state {get; set;}
        public String country {get; set;}
        public String zip {get; set;}
        public String twitter_handle {get; set;}
        public String facebook_handle {get; set;}
        public String linkedin_id {get; set;}
        public List<Funding> funding {get; set;}
    }
}

Then use the following to deserialize it
 
public class MMarkParser {
    public MMarkMetadata company {
        get;
        set;
    }
    
    public void parse() {
        HTTPRequest request = new HTTPRequest();
        request.setEndpoint(
            Label.MatterMarkAPI + 
            '/domains/' +
            'marketinvoice.com' +
            '/companies?key=' + API_KEY
        );  
        request.setMethod('GET');
        
        HTTP h = new HTTP();
        HTTPResponse response = h.send(request); 
        
        this.company = (MMarkMetadata.Company) JSON.deserialize(response.getBody(), MMarkMetadata.Company.class);
        System.debug(wrapper);
    }
}

I would start with the simpilest visualforce page and see if this works

 
<apex:page controller="MMarkParser">
    <apex:form>
        <apex:pageBlock title="company info">
            <apex:pageBlockButtons>
                <apex:commandButton value="parse" action="{!parse}" reRender="companyInfo" />
            </apex:pageBlockButtons>
            <apex:outputPanel id="companyInfo">
                <apex:outputText value="{!company.name}"/>
            </apex:outputPanel>
        </apex:pageBlock>
    </apex:form>
</apex:page>
If this doesn't work, please provide the output of the debug call

All Answers

pconpcon
The VERY FIRST THING I would do would be to deactivate that key and generate a new one.  Now that it has been posted publicly online, it's useless.  Do this first so that a nefarious person doesn't do naughty things.

The problem is that your structure for your wrapper object is not correct.  Looking at the documenation [1] for the /companies endpoint, you need a different wrapper all together.  If you where to specify the company id in the url, then you could use what you have with this endpoint [2] and deserialize it.
 
public class MMarkParser {
    public MMarkWrapper.mmark_company_profile wrapper {
        get;
        set;
    }
    
    public void parse() {
        
        //request class
        HTTPRequest request = new HTTPRequest();
        // Note updated URL
        request.setEndpoint(Label.MatterMarkAPI+'/domains/'+ 'marketinvoice.com' +'/companies/143115?key=' +'c878f447941828d91d53ffbebae068cdb7624fb257cca98e2672e8148e039c1c');  
        request.setMethod('GET');
        
        //response class
        HTTP h = new HTTP();
        HTTPResponse response = h.send(request); 
        
        
        company = (MMarkWrapper.mmark_company_profile) JSON.deserialize(response.getBody(), MMarkWrapper.mmark_company_profile.class);
    }
}

However for the list method [1] you need a different approach
 
public class MMarkMetadata {
    public class ListCompany {
        public String company_name {get; set;}
        public String domain {get; set;}
        public String id {get; set;}
        public String url {get;set;}
    }

    public class Meta {
        public Integer total_record_count {get; set;}
        public Integer total_pages {get; set;}
        public Integer current_page {get; set;}
        public Integer per_page {get; set;}
    }

    public class CompanyListWrapper {
        public Meta meta {get; set;}
        public List<ListCompany> companies {get; set;}
    }
}
then you would deserialize it like so
public class MMarkParser {
    private static String API_KEY = 'aabbcc';

    public MMarkMetadata.CompanyListWrapper wrapper {
        get;
        set;
    }
    
    public void parse() {
        HTTPRequest request = new HTTPRequest();
        request.setEndpoint(
            String.join(
                new List<String> {
                    Label.MatterMarkAPI,
                    'domains',
                    'marketinvoice.com',
                    'companies'
                }, '/'
            ) + ?key=' + API_KEY
        );  
        request.setMethod('GET');
        
        HTTP h = new HTTP();
        HTTPResponse response = h.send(request); 
        
        this.wrapper = (MMarkMetadata.CompanyListWrapper ) JSON.deserialize(response.getBody(), MMarkMetadata.CompanyListWrapper .class);   
    }
}
NOTE: This code has not been tested and may contain typographical or logical errors

[1] https://docs.mattermark.com/api_v1/companies_list/index.html
[2] https://docs.mattermark.com/api_v1/company_details/index.html
Kamil MieczakowskiKamil Mieczakowski
Thank you for your respone, that was quick! Good point about the Key. This one will no longer work.

However I do not think that a wrong wrapper is the reason here.

That's the API response I am getting from my request class:
 
{
  "name": "MarketInvoice",
  "description": "Don't wait 30-120 days for your invoices to be paid. Take control of your cash flow in 24 hours by selling your invoices online.",
  "website": "marketinvoice.com",
  "mattermark_score": "-37",
  "employees": "105",
  "employees_month_ago": "105",
  "employees_6_months_ago": "109",
  "website_uniques": "35479",
  "mobile_downloads": null,
  "stage": "b",
  "total_funding": "35326875",
  "last_funding_amount": "9550000",
  "last_funding_date": "2016-07-17",
  "location": "london",
  "city": "London",
  "state": null,
  "country": "gbr",
  "zip": null,
  "twitter_handle": "marketinvoice",
  "facebook_handle": "Marketinvoice",
  "linkedin_id": "1293969",
  "funding": [
    {
      "amount": "1600000",
      "currency": "GBP",
      "series": "seed",
      "funding_date": "2010-10-01",
      "news_url": "",
      "source": "derived",
      "investor_ids": [],
      "investors": ""
    },
    {
      "amount": "8000000",
      "currency": "USD",
      "series": "a",
      "funding_date": "2014-12-15",
      "news_url": "http://techcrunch.com/2015/08/17/marketinvoice-more-funding/",
      "source": "derived",
      "investor_ids": [],
      "investors": ""
    },
    {
      "amount": "10000000",
      "currency": "USD",
      "series": "a",
      "funding_date": "2015-08-17",
      "news_url": "http://techcrunch.com/2015/08/17/marketinvoice-more-funding/",
      "source": "derived",
      "investor_ids": [
        778,
        26852
      ],
      "investors": "Northzone, Paul Forster"
    },
    {
      "amount": "7776875",
      "currency": "USD",
      "series": "a",
      "funding_date": "2015-09-17",
      "news_url": "http://techcitynews.com/2015/09/17/british-business-bank-makes-5m-investment-in-marketinvoice/",
      "source": "derived",
      "investor_ids": [
        28708
      ],
      "investors": "British Business Bank"
    },
    {
      "amount": "9550000",
      "currency": "USD",
      "series": "b",
      "funding_date": "2016-07-17",
      "news_url": "http://www.crowdfundinsider.com/2016/07/88052-p2p-platform-marketinvoice-raises-7-2-million-post-brexit-funding/",
      "source": "derived",
      "investor_ids": [
        778,
        3678
      ],
      "investors": "Northzone, MCI Management"
    }
  ],

 
pconpcon
Ok, so you are getting back the results from the single company call.  The URI is just different than what is mentioned in the documentation.  So you'll want to have the following class for your deserialization.  The naming of the fields is the most important part.  Your company information is mostly correct but the funding is not.
 
public class MMarkMetadata {
    public class Funding {
        public String amount {get; set;}
        public String currency {get; set;}
        public String series {get; set;}
        public String funding_date{get; set;}
        public String news_url {get; set;}
        public String source {get; set;}
        public List<Integer> investor_ids {get; set;}
        public String investors {get; set;}
    }

    public class Company {
        public String name {get; set;}
        public String description {get; set;}
        public String website {get; set;}
        public String mattermark_score {get; set;}
        public String employees {get; set;}
        public String employees_month_ago {get; set;}
        public String employees_6_months_ago {get; set;}
        public String website_uniques {get; set;}
        public String mobile_downloads {get; set;}
        public String stage {get; set;}
        public String total_funding {get; set;}
        public String location {get; set;}
        public String city {get; set;}
        public String state {get; set;}
        public String country {get; set;}
        public String zip {get; set;}
        public String twitter_handle {get; set;}
        public String facebook_handle {get; set;}
        public String linkedin_id {get; set;}
        public List<Funding> funding {get; set;}
    }
}

Then use the following to deserialize it
 
public class MMarkParser {
    public MMarkMetadata company {
        get;
        set;
    }
    
    public void parse() {
        HTTPRequest request = new HTTPRequest();
        request.setEndpoint(
            Label.MatterMarkAPI + 
            '/domains/' +
            'marketinvoice.com' +
            '/companies?key=' + API_KEY
        );  
        request.setMethod('GET');
        
        HTTP h = new HTTP();
        HTTPResponse response = h.send(request); 
        
        this.company = (MMarkMetadata.Company) JSON.deserialize(response.getBody(), MMarkMetadata.Company.class);
        System.debug(wrapper);
    }
}

I would start with the simpilest visualforce page and see if this works

 
<apex:page controller="MMarkParser">
    <apex:form>
        <apex:pageBlock title="company info">
            <apex:pageBlockButtons>
                <apex:commandButton value="parse" action="{!parse}" reRender="companyInfo" />
            </apex:pageBlockButtons>
            <apex:outputPanel id="companyInfo">
                <apex:outputText value="{!company.name}"/>
            </apex:outputPanel>
        </apex:pageBlock>
    </apex:form>
</apex:page>
If this doesn't work, please provide the output of the debug call
This was selected as the best answer
Kamil MieczakowskiKamil Mieczakowski
Just a couple issues. I think I know how to address them, but would rather hear it from a pro before moving forwards. 
 
MMarkWrapp - Line 0 - Unknown property 'MMarkParser.company'
MMarkParser - Line21 - Variable does not exist: wrapper

 
pconpcon
Ok, line 0 is because of line 21.  The fix is to change line 21 of the controller to be this.company instead