You need to sign in to do that
Don't have an account?
Ivan Winzer
Can not write a field name, expecting a value
So been working with my buddy Greg C and have code that sends data to third party system thru Json Post calls. When creating a new record in salesforce the class fires correctly and it passes over with no issue. Currently working on trigger to push address entries to push over as well. Now when i try to edit a contact record with no address related record the class fires off no issues but soon as you add a address record and try to edit a contacat i get the "System.JSONException: Can not write a field name, expecting a value" error message for the following line:
Class.MagentoUtility.getAddresses: line 78, column 1
Class.MagentoUtility.magentoPost: line 118, column 1
Here is the class that i am using and the trigger which im not sure how to get this to pass over without the message.
Class:
Trigger:
Any input is greatly appreciated.
Ivan
Class.MagentoUtility.getAddresses: line 78, column 1
Class.MagentoUtility.magentoPost: line 118, column 1
Here is the class that i am using and the trigger which im not sure how to get this to pass over without the message.
Class:
global class MagentoUtility { //This is a future method used to call the methods we need to get a token and then post to Magento. //Since this is executed using a trigger, callouts need to be future methods. As a result, our methods need to be static. @future(callout=true) public static void magentoIntegration(String contactData){ String token = getToken(); magentoPost(token, contactData); } public static String getToken() { //Retrieve Username from Magento Setting (custom metadata type) String magentoUsername = [SELECT Value__c FROM Magento_Setting__mdt WHERE DeveloperName = 'magentoUsername' LIMIT 1].Value__c; //Retrieve Password from Magento Setting (custom metadata type) String magentoPassword = [SELECT Value__c FROM Magento_Setting__mdt WHERE DeveloperName = 'magentoPassword' LIMIT 1].Value__c; //Retrieve Token Enpoint from Magento Setting (custom metadata type) String tokenEndpoint = [SELECT Value__c FROM Magento_Setting__mdt WHERE DeveloperName = 'tokenEndpoint' LIMIT 1].Value__c; //String UserName = 'username'; /////Retrieve token///// HttpRequest req = new HttpRequest(); req.setEndpoint(tokenEndpoint); req.setMethod('POST'); JSONGenerator gen = JSON.createGenerator(true); gen.writeStartObject(); gen.writeStringField('username', magentoUsername); gen.writeStringField('password',magentoPassword); gen.writeEndObject(); String jsonA = gen.getAsString(); System.debug('jsonMaterials'+jsonA); //Specify the required username and password to access the endpoint //String authBody = jsonA; //'{"username":"' + magentoUsername + '", "password" : "' + magentoPassword + '" }'; //String parseJson = System.debug(Json.serialize(authBody)); req.setBody(jsonA); req.setHeader('Content-Type', 'application/json; charset=UTF-8'); Http http = new Http(); HTTPResponse res = http.send(req); //JSONParser parser = JSON.createParser(res.getBody()); System.debug('Response: ' + res.getBody()); String authToken = res.getBody(); authToken = authToken.replace('\\', ''); authToken = authToken.replace('"', ''); //String authToken = json.Replace("\", ""); return authToken; //return authToken; //String parseJson = Json.serialize(authToken); //return parseJson; } public static Map<Id,String> getAddresses(List<Contact> contactList) { List<Contact> data = new List<Contact>(); data = [Select Id,(Select Id, FirstName__c, LastName__c, Country__c, Zip__c, State__c, Phone_Number__c, Primary_Billing_Address__c, Default_Shipping_Address__c, Address__c, Address2__c, UUID__c From R00N40000001gQKfEAM) From Contact c WHERE (c.Id IN (SELECT Contact__c FROM ShipTo_Address__c)) AND ( c.Id IN :contactList)]; //data = [Select Id,(Select Id From ShipTo_Addresses__r) From Contact c WHERE (c.Id IN (SELECT Contact__c FROM ShipTo_Address__c)) AND ( c.Id IN :contactList)]; Map<Id, String> contactAddressMap = new Map<Id, String>(); for(Contact c : data){ //Create JSON Generator for creating JSON Array for addresses JSONGenerator gen = JSON.createGenerator(true); for(ShipTo_Address__c cd : c.R00N40000001gQKfEAM){ //for(ShipTo_Address__c cd : c.ShipTo_Addresses__r){ //Build address data for each Contact passed by trigger //gen.writeStartObject(); //gen.writeFieldName('addresses'); gen.writeStartArray(); if (cd.FirstName__c != Null){ gen.writeStringField('firstname', cd.FirstName__c); } else { gen.writeStringField('firstname',''); } gen.writeStringField('lastname', cd.LastName__c); gen.writeStringField('countryId', cd.Country__c); gen.writeStringField('postalcode', cd.ZIP__c); gen.writeStringField('state', cd.State__c); gen.writeStringField('telephone', cd.Phone_Number__c); gen.writeBooleanField('defaultBilling', cd.Primary_Billing_Address__c); gen.writeBooleanField('defaultShipping', cd.Default_Shipping_Address__c); if ( cd.Address2__c != null ){ gen.writeStringField('street', cd.Address__c + ' ' + cd.Address2__c); } else { gen.writeStringField('street', cd.Address__c); } //To avoid null pointer exception if( cd.UUID__c != null ) { gen.writeStringField('uuid', cd.UUID__c); } //gen.writeEndObject(); gen.writeEndArray(); gen.close(); } //Add the child address to the map of the parent Contact ID and the address data contactAddressMap.put(c.Id, gen.getAsString()); } return contactAddressMap; } public static void magentoPost(String token, String contactData) { //Retrieve Token Endpoint from Magento Setting (custom metadata type) String syncEndpoint = [SELECT Value__c FROM Magento_Setting__mdt WHERE DeveloperName = 'syncEndpoint' LIMIT 1].Value__c; //Deserialize the JSON string passed by the Contact trigger. We have to pass this as JSON because future methods don't support passing sObjects. List<Contact> contactList = (List<Contact>) Json.deserialize(contactData, List<Contact>.class); //Obtain the address data from child object Map<Id, String> addressMap = new Map<Id, String>(); addressMap = getAddresses(contactList); //Loop through the new Contacts for( Contact c : contactList ) { HttpRequest req = new HttpRequest(); req.setEndpoint(syncEndpoint); req.setMethod('POST'); req.setHeader('Content-Type', 'application/json; charset=UTF-8'); req.setHeader('Authorization', 'Bearer ' + token); JSONGenerator gen = JSON.createGenerator(true); //We need to create { "customer": { //writeStartObject() - Writes the starting marker of a JSON object ('{'). gen.writeStartObject(); gen.writeFieldName('customer'); gen.writeStartObject(); gen.writeStringField('firstname',c.FirstName); gen.writeStringField('lastname',c.LastName); gen.writeStringField('email',c.Email); gen.writeStringField('telephone',c.HomePhone); gen.writeStringField('contact_sf_id',c.Id); gen.writeDateTimeField('sfdc_updated_at',c.LastModifiedDate); if( c.Account.RMS_Account_Number__c != null ){ gen.writeStringField('rms_account_no', c.Account.RMS_Account_Number__c); } gen.writeStringField('customer_group_code',c.Pricing_Profile__c); if( c.Revel_Id__c != null ) { gen.writeStringField('revel_id', c.Revel_Id__c); } //To avoid null pointer exception if( c.Magento_Associate_to_Website__c != null ) { gen.writeStringField('website_id', c.Magento_Associate_to_Website__c); } //To avoid null pointer exception if( c.Store_ID__c != null ) { gen.writeStringField('store_id', c.Store_ID__c); } //To avoid null pointer exception if( c.UUID__c != null ) { gen.writeStringField('uuid', c.UUID__c); } //Addresses is a JSON array, so we use writeObjectField method based upon example in Salesforce documentation //Line 47 in their example code - https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_json_jsongenerator.htm if( addressMap.get(c.Id) != null ) { gen.writeObjectField('addresses', addressMap.get(c.Id)); } //Expected JSON data ends in '} }' so we call "writeEndObject" twice gen.writeEndObject(); gen.writeEndObject(); String jsonStr = gen.getAsString(); System.debug('JSON String: ' + jsonStr); req.setBody(jsonStr); System.debug('Req Body: ' + req.getBody()); System.debug('Req Body as Blob: ' + req.getBodyAsBlob()); Http http = new Http(); HTTPResponse res = http.send(req); System.debug('Response Body: ' + res.getBody()); System.debug('Response Body as Blob: ' + res.getBodyAsBlob()); } } }
Trigger:
trigger MainContactTrigger on Contact (before update, before insert, after update, after insert) { DuplicateEmailFilter def = new DuplicateEmailFilter(); Map<id,Contact> oldMap = trigger.oldMap; CreateAccountFromContact accountCreation = New CreateAccountFromContact(); if(oldMap == null){ oldMap = new Map<Id,Contact>(); } if(Trigger.isBefore){ // // For the before creation we check if the contact is getting created by a real user then we use // the Duplicate Email Filter to generate an error preventing the contact from being created. if(!IntegrationUtils.isIntegrationUser()){ def.processContacts(trigger.new, oldMap); } if( Trigger.isInsert && !IntegrationUtils.ignoreForAutoAccountUser() ) { accountCreation.ProcessBatchContactsWEmail(trigger.new,trigger.oldMap); } else if( Trigger.isInsert || Trigger.isUpdate ) { accountCreation.ProcessBatchContacts(trigger.new,trigger.oldMap); } } else if(Trigger.isAfter){ // // This is the After trigger - we just need to check if the email address is already // in use in the duplicate email filter. // if it is being created by the integration user then in the DEF we flag the contact as having // a duplicate. Leaving it up to the Salesforce Admin to clean it up. // if(IntegrationUtils.isIntegrationUser()){ def.processContacts(trigger.new, oldMap); } //Magento Integration if( Trigger.isInsert || Trigger.isUpdate ){ String jsonString = json.serialize(Trigger.NEW); MagentoUtility.magentoIntegration(jsonString); } } }
Any input is greatly appreciated.
Ivan