Model record ID update with Javascript snippet

Hi
I am using Skuid V1 with Salesforce

I had a use case where i needed to do some logic and return Contact records to Skuid to present to the User (logic i could not do in Skuid to select the Contacts. So i created an Invocable Method in Slaforce and wrote a JavaScript snippet to make the call and populate a Model. I am able to create the records with all the data i get in the call, but i can’t set the record IDs on the model with the ones i get from my call from Salesforce (the actual contact sf ID) . Skuid puts a temporary id and i can’t seem to overwrite it.
If anyone can help me or give me a workaround would be appreciat it

var params = arguments[0],
$ = skuid.$;

try {

var contact = skuid.model.getModel('contact').getFirstRow();

var request =  {inputs:[{ "last_name" : contact.LastName,"first_name" : contact.FirstName, "social" : contact.X1st_Social_Security__c}]}
console.log('request ' + request);
console.log('request size' + request.length);
console.log(JSON.stringify(request));

$.ajax('/services/data/v48.0/actions/custom/apex/Contact_Duplicate_Managment_Skuid', {
    data: JSON.stringify(request),
    type: 'POST',
    //crossDomain: true,
    //dataType: "json",
    beforeSend: function(xhr) {
        xhr.setRequestHeader('Authorization', 'Bearer ' + sforce.connection.sessionId);
        xhr.setRequestHeader('Content-Type', 'application/json');
    },
    success: function(response) {
       console.log('response :' + response.length);
       var contact_duplicates = skuid.model.getModel('contact_duplicates');

       var row;
       for (let i = 0; i <response.length; i++) {
            row = contact_duplicates.createRow()
            contact_duplicates.updateRow(row,{Id:response[i].outputValues.id,FirstName:response[i].outputValues.first_name})
            console.log('response :' + response[i].outputValues.id);
        }
    },
    error: function(jqXHR, textStatus, errorThrown) {
        //console.log([jqXHR, textStatus, errorThrown]);
    }
});

} catch (e) {
console.log(e);
alert(e);
}

here is my code

I’ve created a skuid “custom” library that has a function that operates as you need it. The way it works is it tricks SKUID into thinking a newly created row is actually an existing row in the system (applying an ID for an existing database row, rather than using a skuid temp ID)

I’ll post the specific function(s) here for creating a row / rows that should be updated rather than inserted.

// skuid.custom.createUpdateExistingRow(ourModel,row)
//  Create a row for an already existing Salesforce object with any specified fields acting as updates to the row when saving
//  createRow will normally assume the newly created row needs to be inserted, but if this is an existing row
//  we will instead be updating the row when saving the model
//  row is an object of field value pairs and must include a salesforce Id field
skuid.custom.createUpdateExistingRow = function (model, row) {
	if (row === undefined) {
		return false;
	}
	if (row.Id === undefined) {
		return false;
	}
	const retRows = model.adoptRows([{ Id: row.Id }], { doAppend: true });
	let retRow;
	if (retRows !== undefined && retRows.length > 0) {
		retRow = retRows[0];
	}

	const upd = row;
	delete upd.Id;
	if (upd !== {}) {
		model.updateRow(model.data[model.data.length - 1], upd);
	}

	return retRow;
}

// skuid.custom.createUpdateExistingRows(ourModel,rows)
//  Create rows for already existing Salesforce objects with any specified fields acting as updates to those rows when saving
//  createRow will normally assume the newly created row needs to be inserted, but if this is an existing row
//  we will instead be updating the row when saving the model
//  rows is an array of objects of field value pairs and must include a salesforce Id field
skuid.custom.createUpdateExistingRows = function (model, rows) {
	if (rows === undefined) {
		return false;
	}
	
	// Construct our adoptrows and updaterows array / object
	const rowsIds = [];
	const rowsUpdates = {};
	for (let i = 0; i < rows.length; i++) {
		const row = rows[i];
		if (row.Id === undefined) {
			return false;
		}

		const id = row.Id;
		rowsIds.push({ Id: id });
		delete row.Id;
		rowsUpdates[id] = row;
	}

	// First adopt the rows with just the row IDs
	let retRows = model.adoptRows(rowsIds, { doAppend: true });
	if (retRows === undefined) {
		return false;
	}

	// Now update the rows with all the other fields as updates
	// This causes all these rows / fields to be treated as needing to be updated when saved
	// which doesn't happen on a regular adoptRows as set up in the above adoptRows function call
	retRows = model.updateRows(rowsUpdates);

	return retRows;
}

thank you
i will give it a try

One note,

The function I posted is designed for the purpose of updating existing rows in the system with new values, so it will cause any values (other than the ID field) to be treated as needing an update.

If the data you’re pulling from AJAX is existing database data such that you’re not needing to update the rows, you can probably get away with just using adoptRows alone.

For example:

model.adoptRows([
{Id: row1SalesforceId, Field1: Value1, Field2: Value2},
{Id: row2SalesforceId, Field1: Value1, Field2: Value2}
],
{doAppend:true});