I am still currently exploring in APIM. I have a payload in payload #1, which I want to transform into another payload # 2(expected).
How would I edit my policy to construct this pay load?
Payload 1
{
"dependtee_name": "Steve",
"depdentee_last_name": "Rogers",
"dependtee_comment" : "This is test",
"file": "file.txt",
"file_type": "text file",
"insurer_name": "Steve",
"insurer_last_name": "Rogers",
"insurer_comment" : "This is test",
"extra_info": "This is comments"
}
Payload 2 - Expected
{
"dependtee_info": {
"name": "Steve",
"last_name": "Rogers"
},
"file_details": {
"all_file": [ "file.txt", "null" ],
"fileFormat": "text file"
},
"insurer_info": {
"i_name": "Tony",
"i_last_name": "Stark"
},
"extra_info": "This is comments"
}
Current Code
<policies>
<inbound>
<base />
<return-response>
<set-status code="200" reason="ok" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>#{
var body = context.Request.Body.As<JObject>(true);
var transformedBody = new JObject();
transformedBody["extra_info"] = body["extra_info"];
var dependentee= new JObject();
dependetee["name"] = body["dependtee_name"];
dependentee["lastName"] = body["depdentee_last_name"];
transformedBody["dependtee_info"] = dependentee;
var file_details = new JObject();
dependentee["all_file"] = body["file"];
dependentee["fileFormat"] = body["file_type"];
transformedBody["file_details"] = file_details;
var insurer_info = new JObject();
dependetee["i_name"] = body["insurer_name"];
dependentee["i_last_name"] = body["insurer_last_name"];
transformedBody["insurer_info"] = insurer_info;
return transformedBody.ToString();
}</set-body>
</return-response>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
Looking to change the body specifically for the file.
I want to know how I can add those square brackets in my expected payload.
Payload 2 should have more than one value for key "all_file", but I want to be able to get it from Payload 1.
Thank you for your help
You have to create a JArray and Add the strings and assign the JArray to the parent object:
var file_details = new JObject();
var all_File = new JArray();
all_File.Add(body["extra_info"]);
all_File.Add("null"); // does not makes sense to a null string
file_details["all_file"] = all_File;
file_details["fileFormat"] = body["file_type"];
transformedBody["file_details"] = file_details;
I do not understand the purpose of "null" in Payload 2 - Expected:
"all_file": [ "file.txt", "null" ],
Where does it comes from? And why is it a string "null" and not null?
Here's complete fixed policy:
<policies>
<inbound>
<base />
<return-response>
<set-status code="200" reason="ok" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>#{
var body = context.Request.Body.As<JObject>(true);
var transformedBody = new JObject();
transformedBody["extra_info"] = body["extra_info"];
var dependentee= new JObject();
dependentee["name"] = body["dependtee_name"];
dependentee["lastName"] = body["depdentee_last_name"];
transformedBody["dependtee_info"] = dependentee;
var file_details = new JObject();
var all_File = new JArray();
all_File.Add(body["extra_info"]);
all_File.Add("null"); // does not makes sense to use a null string
file_details["all_file"] = all_File;
file_details["fileFormat"] = body["file_type"];
transformedBody["file_details"] = file_details;
var insurer_info = new JObject();
insurer_info["i_name"] = body["insurer_name"];
insurer_info["i_last_name"] = body["insurer_last_name"];
transformedBody["insurer_info"] = insurer_info;
return transformedBody.ToString();
}</set-body>
</return-response>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
Result:
Related
I am using C# syntax to transform payload body Using conditional statements to transform body, I want to transform one key of the payload body using conditional statement if possible. More explanation of the scenario is shown in code below.
I tried to implement what I am trying to achieve but I get a error. Not sure if its just my syntax, or putting the logic there would make sense or not.
If this is the payload:
{
"dependentee_name": "Steve",
"dependentee_last_name": "Rogers",
"dependentee_comment" : "This is test",
"dependentee_relationship_primary" : "Parent",
"dependentee_relationship_secondary" : "null",
"insurer_name": "Steve",
"insurer_last_name": "Rogers",
"insurer_comment" : "This is test",
"extra_info": "This is comments"
}
As shown in the payload has a key dependentee_relationship_primary which has value Parent, so the expected transformed body would be as follows:
{
"dependentee_info": {
"name": "Steve",
"last_name": "Rogers"
},
"insurer_info": {
"i_name": "Tony",
"i_last_name": "Stark"
},
"extra_info" : "This is comments",
"relationship_type" : "Parent"
}
If this is the payload:
{
"dependentee_name": "Steve",
"dependentee_last_name": "Rogers",
"dependentee_comment" : "This is test",
"dependentee_relationship_primary" : "null",
"dependentee_relationship_secondary" : "Uncle",
"insurer_name": "Steve",
"insurer_last_name": "Rogers",
"insurer_comment" : "This is test",
"extra_info": "This is comments"
}
As shown in the payload has a key dependentee_relationship_secondaru which has value Uncle, so the expected transformed body would be as follows:
{
"dependentee_info": {
"name": "Steve",
"last_name": "Rogers"
},
"insurer_info": {
"i_name": "Tony",
"i_last_name": "Stark"
},
"extra_info" : "This is comments",
"relationship_type" : "Uncle"
}
I have attempted the code so far, but I run into an error
<policies>
<inbound>
<base />
<return-response>
<set-status code="200" reason="ok" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>#{
var body = context.Request.Body.As<JObject>(true);
var transformedBody = new JObject();
transformedBody["extra_info"] = body["extra_info"];
var dependentee= new JObject();
dependetee["name"] = body["dependtee_name"];
dependentee["lastName"] = body["depdentee_last_name"];
transformedBody["dependtee_info"] = dependentee;
var insurer_info = new JObject();
dependetee["i_name"] = body["insurer_name"];
dependentee["i_last_name"] = body["insurer_last_name"];
transformedBody["insurer_info"] = insurer_info;
if (body["dependentee_relationship_primary"] !=null)
{
transformedBody["relationship_type"] = body["dependentee_relationship_primary"];
}
else if (body["dependentee_relationship_secondary"] !=null) {
transformedBody["relationship_type"] = body["adultrelationship"];
}
return transformedBody.ToString();
}</set-body>
</return-response>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
Duplicate of Azure API Management Policies - Using conditional statements - For Payloads
First of all, it's a good idea to fix the long-existing typo issues like dependetee which I fixed for you already in:
Azure API Management (Policies)
You have to check if
the body has a child dependentee_relationship_primary
the property dependentee_relationship_primary is not null
the property dependentee_relationship_primary is not an empty string
if (body.ContainsKey("dependentee_relationship_primary") && body["dependentee_relationship_primary"].Type != JTokenType.Null && !string.IsNullOrEmpty(body["dependentee_relationship_primary"].Value<string>()))
{
transformedBody["relationship_type"] = body["dependentee_relationship_primary"];
}
The complete policy:
<policies>
<inbound>
<base />
<return-response>
<set-status code="200" reason="ok" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>#{
var body = context.Request.Body.As<JObject>(true);
var transformedBody = new JObject();
transformedBody["extra_info"] = body["extra_info"];
var dependentee= new JObject();
dependentee["name"] = body["dependtee_name"];
dependentee["lastName"] = body["depdentee_last_name"];
transformedBody["dependtee_info"] = dependentee;
var insurer_info = new JObject();
insurer_info["i_name"] = body["insurer_name"];
insurer_info["i_last_name"] = body["insurer_last_name"];
transformedBody["insurer_info"] = insurer_info;
if (body.ContainsKey("dependentee_relationship_primary") && body["dependentee_relationship_primary"].Type != JTokenType.Null && !string.IsNullOrEmpty(body["dependentee_relationship_primary"].Value<string>()))
{
transformedBody["relationship_type"] = body["dependentee_relationship_primary"];
}
else if (body.ContainsKey("dependentee_relationship_secondary") && body["dependentee_relationship_secondary"].Type != JTokenType.Null && !string.IsNullOrEmpty(body["dependentee_relationship_secondary"].Value<string>()))
{
transformedBody["relationship_type"] = body["adultrelationship"];
}
return transformedBody.ToString();
}</set-body>
</return-response>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
Result:
BTW:
Your condition does not make sense:
There's no adultrelationship defined.
I am using C# syntax to transform payload body Using conditional statements to transform body, I want to transform one key of the payload body using conditional statement if possible.
More explanation of the scenario is shown in code below. I tried to implement what I am trying to achieve but I get a error.
Not sure if its just my syntax, or putting the logic there would make sense or not.
If this is the payload:
{
"dependentee_name": "Steve",
"dependentee_last_name": "Rogers",
"dependentee_comment": "This is test",
"dependentee_relationship_primary": "Parent",
"dependentee_relationship_secondary": "null",
"insurer_name": "Steve",
"insurer_last_name": "Rogers",
"insurer_comment": "This is test",
"extra_info": "This is comments"
}
As shown in the payload has a key dependentee_relationship_primary which has value Parent, so the expected transformed body would be as follows:
{
"dependentee_info": {
"name": "Steve",
"last_name": "Rogers"
},
"insurer_info": {
"i_name": "Tony",
"i_last_name": "Stark"
},
"extra_info": "This is comments",
"relationship_type": "Parent"
}
If this is the payload:
{
"dependentee_name": "Steve",
"dependentee_last_name": "Rogers",
"dependentee_comment": "This is test",
"dependentee_relationship_primary": "null",
"dependentee_relationship_secondary": "Uncle",
"insurer_name": "Steve",
"insurer_last_name": "Rogers",
"insurer_comment": "This is test",
"extra_info": "This is comments"
}
As shown in the payload has a key dependentee_relationship_secondary which has value Uncle, so the expected transformed body would be as follows:
{
"dependentee_info": {
"name": "Steve",
"last_name": "Rogers"
},
"insurer_info": {
"i_name": "Tony",
"i_last_name": "Stark"
},
"extra_info": "This is comments",
"relationship_type": "Uncle"
}
I have attempted the code so far, but I run into an error
<policies>
<inbound>
<base />
<return-response>
<set-status code="200" reason="ok" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>#{
var body = context.Request.Body.As<JObject>(true);
var transformedBody = new JObject();
transformedBody["extra_info"] = body["extra_info"];
var dependentee= new JObject();
dependetee["name"] = body["dependtee_name"];
dependentee["lastName"] = body["depdentee_last_name"];
transformedBody["dependtee_info"] = dependentee;
var insurer_info = new JObject();
dependetee["i_name"] = body["insurer_name"];
dependentee["i_last_name"] = body["insurer_last_name"];
transformedBody["insurer_info"] = insurer_info;
if (body["dependentee_relationship_primary"] !=null)
{
transformedBody["relationship_type"] = body["dependentee_relationship_primary"];
}
else if (body["dependentee_relationship_secondary"] !=null) {
transformedBody["relationship_type"] = body["adultrelationship"];
}
return transformedBody.ToString();
}</set-body>
</return-response>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
First of all, it's a good idea to fix the long-existing typo issues like dependetee which I fixed for you already in:
Azure API Management (Policies)
You have to check if
the body has a child dependentee_relationship_primary
the property dependentee_relationship_primary is not null
the property dependentee_relationship_primary is not an empty string
if (body.ContainsKey("dependentee_relationship_primary") && body["dependentee_relationship_primary"].Type != JTokenType.Null && !string.IsNullOrEmpty(body["dependentee_relationship_primary"].Value<string>()))
{
transformedBody["relationship_type"] = body["dependentee_relationship_primary"];
}
The complete policy:
<policies>
<inbound>
<base />
<return-response>
<set-status code="200" reason="ok" />
<set-header name="Content-Type" exists-action="override">
<value>application/json</value>
</set-header>
<set-body>#{
var body = context.Request.Body.As<JObject>(true);
var transformedBody = new JObject();
transformedBody["extra_info"] = body["extra_info"];
var dependentee= new JObject();
dependentee["name"] = body["dependtee_name"];
dependentee["lastName"] = body["depdentee_last_name"];
transformedBody["dependtee_info"] = dependentee;
var insurer_info = new JObject();
insurer_info["i_name"] = body["insurer_name"];
insurer_info["i_last_name"] = body["insurer_last_name"];
transformedBody["insurer_info"] = insurer_info;
if (body.ContainsKey("dependentee_relationship_primary") && body["dependentee_relationship_primary"].Type != JTokenType.Null && !string.IsNullOrEmpty(body["dependentee_relationship_primary"].Value<string>()))
{
transformedBody["relationship_type"] = body["dependentee_relationship_primary"];
}
else if (body.ContainsKey("dependentee_relationship_secondary") && body["dependentee_relationship_secondary"].Type != JTokenType.Null && !string.IsNullOrEmpty(body["dependentee_relationship_secondary"].Value<string>()))
{
transformedBody["relationship_type"] = body["adultrelationship"];
}
return transformedBody.ToString();
}</set-body>
</return-response>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
Result:
BTW:
Your condition does not make sense:
There's no adultrelationship defined.
I am writing javascript (CSOM) code in SharePoint to add items to SharePoint Calendar app (list).
I want to add these records only if calendar is free during the specified time.
i.e in below ex, I want to check if calendar is free from 08:00 to 08:15 before adding
var itemCreateInfo = new SP.ListItemCreationInformation();
var listItem = list.addItem(itemCreateInfo);
var startdate = new Date('2017-10-21 08:00 GMT+0000').toISOString();
var enddate = new Date('2017-10-21 08:15 GMT+0000').toISOString();
listItem.set_item("Title", "My Event");
listItem.set_item("EventDate", startdate);
listItem.set_item("EndDate", enddate);
listItem.set_item("Location", "MyCalander");
listItem.update();
Here is a query you can use: (The caml value looks terrible so I'll post the xml below)
function queryCalendar(startDate, endDate) {
var context = SP.ClientContext.get_current();
var list = context.get_web().get_lists().getByTitle("Calendar");
var caml = "\n<View>\n <Query>\n <Where>\n <And>\n <Lt>\n <FieldRef Name='EventDate' />\n <Value Type='DateTime' IncludeTimeValue='True' StorageTZ='TRUE'>" + endDate.toISOString() + "</Value>\n </Lt>\n <Gt>\n <FieldRef Name='EndDate' />\n <Value Type='DateTime' IncludeTimeValue='True' StorageTZ='TRUE'>" + startDate.toISOString() + "</Value>\n </Gt>\n </And>\n </Where>\n </Query>\n <ViewFields>\n <FieldRef Name='EventDate' />\n <FieldRef Name='EndDate' />\n <FieldRef Name='Title' />\n </ViewFields>\n</View>\n\n";
var query = new SP.CamlQuery();
query.set_viewXml(caml);
var listItems = list.getItems(query);
context.load(listItems);
context.executeQueryAsync(function (sender, args) {
if (listItems.get_count() > 0) {
console.warn("That time is already booked");
}
else {
console.log("that time is good");
}
}, function (sender, args) {
console.error(args.get_message());
});
}
Here is how I am calling it:
SP.SOD.executeOrDelayUntilScriptLoaded(function () {
queryCalendar(new Date(2019, 4, 27, 8), new Date(2019, 4, 27, 9));
}, "SP.js");
I use the following XML for the CAML:
<View>
<Query>
<Where>
<And>
<Lt>
<FieldRef Name='EventDate' />
<Value Type='DateTime' IncludeTimeValue="True" StorageTZ='TRUE'>enddate</Value>
</Lt>
<Gt>
<FieldRef Name='EndDate' />
<Value Type='DateTime' IncludeTimeValue="True" StorageTZ='TRUE'>starttime</Value>
</Gt>
</And>
</Where>
</Query>
<ViewFields>
<FieldRef Name='EventDate' />
<FieldRef Name='EndDate' />
<FieldRef Name='Title' />
</ViewFields>
</View>
Make sure to replace "enddate" and "startdate" with a proper date value and use date.toISOString() method (which might not work in IE).
I have a scenario where i need to display an Alert banner with the title column in my list.
Below is the code which iam trying to use . But it is not displaying correctly. Can any one let me know Errorl
<script type="text/ecmascript" language="ecmascript">
var strStatusID;
function showInfo(strMessage) {
alert("Code sucess");
strStatusID = SP.UI.Status.addStatus(strMessage, true);
alert(strMessage.toString());
SP.UI.Status.setStatusPriColor(strStatusID, "yellow");
}
</script>
<asp:Panel ID="Panel1" runat="server">
<asp:Label ID="lblScripter" runat="server" Visible="false"></asp:Label>
</asp:Panel>
public void LoadGrid()
{
//System.Diagnostics.Debugger.Break();
var oSPWeb = SPContext.Current.Web;
SPList oSpList = oSPWeb.Lists["AlertList"];
SPQuery oQuery = new SPQuery();
oQuery.Query = #"<Where><Neq><FieldRef Name='NoOfDays' /><Value Type='Calculated'>0:00</Value></Neq></Where>";
SPListItemCollection _AlertListCollection = oSpList.GetItems(oQuery);
DataTable Table_Calendar = _AlertListCollection.GetDataTable();
if (Table_Calendar != null)
{
foreach (SPListItem item in _AlertListCollection)
{
MessageShow = item["Title"].ToString();
}
// strStatusID = SP.UI.Status.addStatus(strMessage, true);
lblScripter.Text = "<Script language='javascript;>showInfo('" + MessageShow + "');</script>";
}
else
{
lblScripter.Visible = false;
}
}
<asp:Timer runat="server" ID="UpdateTimer" Interval="6000" OnTick="UpdateTimer_Tick" />
<asp:UpdatePanel runat="server" ID="TimedPanel" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="UpdateTimer" EventName="Tick" />
</Triggers>
<ContentTemplate>
<asp:Label runat="server" ID="DateStampLabel" />
<asp:Label ID="lblScripter" runat="server"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
protected void UpdateTimer_Tick(object sender, EventArgs e)
{
System.Diagnostics.Debugger.Break();
DateStampLabel.Text = DateTime.Now.ToString();
DateTime Currenttime = DateTime.Parse(DateStampLabel.Text.ToString());
var oSPWeb = SPContext.Current.Web;
SPList oSpList = oSPWeb.Lists["Alertlist"];
SPQuery oQuery = new SPQuery();
oQuery.Query = #"<Where><Neq><FieldRef Name='NoOfDays' /><Value Type='Calculated'>0:00</Value></Neq></Where>";
SPListItemCollection _AlertListCollection = oSpList.GetItems(oQuery);
DataTable Table_Calendar = _AlertListCollection.GetDataTable();
if (Table_Calendar != null)
{
foreach (SPListItem item in _AlertListCollection)
{
MessageShow = item["Title"].ToString();
Enddate = DateTime.Parse(item["EndDate"].ToString());
}
lblScripter.Text = #"<script type=""text/javascript"">SP.SOD.executeOrDelayUntilScriptLoaded(function() {showInfo('" + MessageShow + "');}, 'sp.js');</script>";
if (Currenttime >= Enddate)
{
lblScripter.Text = "hi after date tim refreshed";
lblScripter.Text = #"<script type=""text/javascript"">SP.SOD.executeOrDelayUntilScriptLoaded(function() {removeAllInfos();}, 'sp.js');</script>";
}
}
//else
//{
// lblScripter.Visible = false;
//}
}
Try to set :
lblScripter.Text = #"<script type=""text/javascript"">SP.SOD.executeOrDelayUntilScriptLoaded(function() {showInfo('" + MessageShow + "');}, 'sp.js');</script>"
Most likely this will solve your problem of calling the SP.UI.Status javascript functions before they have been loaded.
I Have solved this PFB code in order to acheive this. Thanks to my friend Hameed who has helped me to acheive the same
<script type="text/ecmascript" language="ecmascript">
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(RegisterMethods);
function RegisterMethods() {
showInfo();
RemoveLastStatus();
}
function showInfo() {
var strMessage = document.getElementById('<%= Message.ClientID %>').value;
var strstatus = document.getElementById('<%= StartStatus.ClientID %>').value;
if (strMessage != null) {
if (strstatus != "false") {
var strStatusID;
strStatusID = SP.UI.Status.addStatus(strMessage);
SP.UI.Status.setStatusPriColor(strStatusID, "red");
document.getElementById('<%= StartStatus.ClientID %>').value = "false";
document.getElementById('<%= StatusId.ClientID %>').value = strStatusID;
}
}
}
function RemoveLastStatus() {
var statusId = document.getElementById('<%= StatusId.ClientID %>').value;
var stopStatus = document.getElementById('<%= StopStatus.ClientID %>').value;
if (statusId != null) {
if (stopStatus == "true") {
SP.UI.Status.removeStatus(statusId);
statusId = '';
}
}
}
</script>
<asp:Timer runat="server" ID="UpdateTimer" Interval="5000" OnTick="UpdateTimer_Tick" />
<asp:UpdatePanel runat="server" ID="TimedPanel" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="UpdateTimer" EventName="Tick" />
</Triggers>
<ContentTemplate>
<asp:Label runat="server" ID="DateStampLabel" />
<asp:Label ID="lblScripter" runat="server" Visible="True"></asp:Label>
<asp:HiddenField ID="StartStatus" runat="server" />
<asp:HiddenField ID="StopStatus" runat="server" />
<asp:HiddenField ID="Message" runat="server" />
<asp:HiddenField ID="StatusId" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
CODEBEHIND.cs
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Collections.Generic;
using System.Web;
using System.Drawing;
using System.Globalization;
using System.Data;
using System.Linq;
using Microsoft.SharePoint.Utilities;
namespace ITBANNER
{
public partial class ITOpsBannerUserControl : UserControl
{
String MessageShow = string.Empty;
DateTime Enddate, starttime;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DateStampLabel.Text = DateTime.Now.ToString();
DateTime Currenttime = DateTime.Parse(DateStampLabel.Text.ToString());
var oSPWeb = SPContext.Current.Web;
SPList oSpList = oSPWeb.Lists["AlertList"];
SPListItemCollection items = oSpList.Items;
SPListItem item;
for (int i = 0; i < items.Count; i++)
{
item = items[i];
Console.WriteLine("Index = {0} ID = {1}", i, item.ID);
}
SPListItem item = oSpList.GetItemById(3);
Message.Value = item["Title"].ToString();
starttime = DateTime.Parse(item["StartDate"].ToString());
if (Currenttime >= starttime)
{
StartStatus.Value = "true";
StopStatus.Value = "false";
}
}
}
protected void UpdateTimer_Tick(object sender, EventArgs e)
{
DateStampLabel.Text = DateTime.Now.ToString();
DateTime Currenttime = DateTime.Parse(DateStampLabel.Text.ToString());
var oSPWeb = SPContext.Current.Web;
SPList oSpList = oSPWeb.Lists["AlertList"];
SPListItem item = oSpList.GetItemById(3);
Enddate = DateTime.Parse(item["EndDate"].ToString());
if (Currenttime >= Enddate)
{
StopStatus.Value = "true";
}
}
//public void HideStatusBar()
//{
// string script = "document.onreadystatechange=fnRemoveAllStatus; function fnRemoveAllStatus(){removeAllStatus(true)};";
// this.Page.ClientScript.RegisterClientScriptBlock(typeof(Type), "statusBarRemover", script, true);
//}
}
}
I have the following code block:
<cfset docs1 = StructNew() />
<cfset docs1['content'] = "I am" />
<cfset docs1['ida'] = "23" />
<cfset docs1['solrid'] = "23_solrid" />
<cfset docs1['title'] = "Aaaaa" />
<cfset docs2 = StructNew() />
<cfset docs2['content'] = "the most" />
<cfset docs2['ida'] = "1" />
<cfset docs2['solrid'] = "1_solrid" />
<cfset docs2['title'] = "Bbbb" />
<cfset docs3 = StructNew() />
<cfset docs3['content'] = "crap coder" />
<cfset docs3['ida'] = "7" />
<cfset docs3['solrid'] = "7_solrid" />
<cfset docs3['title'] = "Cccc" />
<cfset docs4 = StructNew() />
<cfset docs4['content'] = "in the whole universe!" />
<cfset docs4['ida'] = "39" />
<cfset docs4['solrid'] = "39_solrid" />
<cfset docs4['title'] = "Dddd" />
<cfscript>
doca = ArrayNew();
ArrayAppend(doca, docs1);
ArrayAppend(doca, docs2);
ArrayAppend(doca, docs3);
ArrayAppend(doca, docs4);
</cfscript>
<cfset forsolr1 = StructNew()>
<cfset forsolr1['docs'] = doca>
<cfset forext1 = SerializeJson(forsolr1)>
<cfdump var="#forsolr1#" label="Struct1">
<cfoutput>
#forext1#
</cfoutput>
<br /><br /><br />
<cfset docsh = StructNew() />
<cfset docsh['23_solrid'] = "I need" />
<cfset docsh['1_solrid'] = "to read" />
<cfset docsh['7_solrid'] = "a lot of" />
<cfset docsh['39_solrid'] = "programming books!" />
<cfset i = 1>
<cfset solrid = "solrid">
<cfset result = ArrayNew(1)>
<cfloop collection="#docsh#" item="key" >
<cfset innerstruct = StructNew()>
<cfset innerstruct['solrid'] = #key#>
<cfset innerstruct['dochighlighted'] = #docsh[key]#>
<cfset result[i] = innerstruct>
<cfset i = i + 1>
</cfloop>
<cfset forsolr = StructNew()>
<cfset forsolr['docs'] = result>
<cfset forext = SerializeJson(forsolr)>
<cfdump var="#forsolr#" label="Struct2">
<cfoutput>
#forext#
</cfoutput>
The result are two objects(struct of array of structs):
First object
{
"docs":[
{
"content":"I am",
"ida":"23",
"solrid":"23_solrid",
"title":"Aaaaa"
},
{
"content":"the most",
"ida":"1",
"solrid":"1_solrid",
"title":"Bbbb"
},
{
"content":"crap coder",
"ida":"7",
"solrid":"7_solrid",
"title":"Cccc"
},
{
"content":"in the whole universe!",
"ida":"39",
"solrid":"39_solrid",
"title":"Dddd"
}
]
}
Second object
{
"docs":[
{
"solrid":"23_solrid",
"dochighlighted":"I need"
},
{
"solrid":"1_solrid",
"dochighlighted":"to read"
},
{
"solrid":"7_solrid",
"dochighlighted":"a lot of"
},
{
"solrid":"39_solrid",
"dochighlighted":"programming books!"
}
]
}
Is it possible to merge these two objects into one in the form of(copy second to the first):
{
"docs":[
{
"content":"I am",
"ida":"23",
"solrid":"23_solrid",
"title":"Aaaaa",
"dochighlighted":"I need"
},
{
"content":"the most",
"ida":"1",
"solrid":"1_solrid",
"title":"Bbbb",
"dochighlighted":"to read"
},
{
"content":"crap coder",
"ida":"7",
"solrid":"7_solrid",
"title":"Cccc",
"dochighlighted":"a lot of"
},
{
"content":"in the whole universe!",
"ida":"39",
"solrid":"39_solrid",
"title":"Dddd",
"dochighlighted":"programming books!"
}
]
}
I had tried structAppend function with no result. This function cannot append deep nested elements. Is it possible to retain order? The reason for that is that the above objects are search engine's results, so it is very important to keep the original order. Is it possible to merge two objects by key reference? The reason that I am asking is that the first object is coming out from the search engine in a specific order (notice the solrid) but the second object may not. Example:
*First object*
{
"docs":[
{
"content":"I am",
"ida":"23",
"solrid":"23_solrid",
"title":"Aaaaa"
},
{
"content":"the most",
"ida":"1",
"solrid":"1_solrid",
"title":"Bbbb"
},
{
"content":"crap coder",
"ida":"7",
"solrid":"7_solrid",
"title":"Cccc"
},
{
"content":"in the whole universe!",
"ida":"39",
"solrid":"39_solrid",
"title":"Dddd"
}
]
}
*Second object*
{
"docs":[
{
"solrid":"39_solrid",
"dochighlighted":"programming books!"
},
{
"solrid":"7_solrid",
"dochighlighted":"a lot of"
},
{
"solrid":"1_solrid",
"dochighlighted":"to read"
},
{
"solrid":"23_solrid",
"dochighlighted":"I need"
}
]
}
Is it possible to achieve the same -as above- merging result?
{
"docs":[
{
"content":"I am",
"ida":"23",
"solrid":"23_solrid",
"title":"Aaaaa",
"dochighlighted":"I need"
},
{
"content":"the most",
"ida":"1",
"solrid":"1_solrid",
"title":"Bbbb",
"dochighlighted":"to read"
},
{
"content":"crap coder",
"ida":"7",
"solrid":"7_solrid",
"title":"Cccc",
"dochighlighted":"a lot of"
},
{
"content":"in the whole universe!",
"ida":"39",
"solrid":"39_solrid",
"title":"Dddd",
"dochighlighted":"programming books!"
}
]
}
Many many thanks,
With honour,
Tom
Greece
This should get you pretty far:
<cffunction name="ArrayOfStructsMerge" returntype="array" access="public" output="yes">
<cfargument name="left" type="array" required="yes">
<cfargument name="right" type="array" required="yes">
<cfargument name="id" type="string" required="yes">
<cfset var result = Duplicate(arguments.left)>
<cfset var element = "">
<cfset var key = "">
<cfset var currentId = "">
<cfset var lookup = StructNew()>
<cfloop array="#result#" index="element">
<cfif IsStruct(element) and StructKeyExists(element, arguments.id)>
<cfset currentId = element[arguments.id]>
<cfset lookup[currentId] = element>
</cfif>
</cfloop>
<cfloop array="#arguments.right#" index="element">
<cfif IsStruct(element) and StructKeyExists(element, arguments.id)>
<cfset currentId = element[arguments.id]>
<cfif StructKeyExists(lookup, currentId)>
<cfloop collection="#element#" item="key">
<cfset lookup[currentId][key] = Duplicate(element[key])>
</cfloop>
<cfelse>
<cfset ArrayAppend(result, Duplicate(element))>
</cfif>
</cfif>
</cfloop>
<cfreturn result>
</cffunction>
It operates non-destructively (without modifying the original objects). Call it like this:
<cfset result = ArrayOfStructsMerge(obj1.docs, obj2.docs, "solrid")>
<cfdump var="#result#">
<cfset a1 = [{id: 1, a: "a1"}, {id: 2, a: "a2"}, {id: 4, d: "d4"}]>
<cfset a2 = [{id: 1, a: "a1-new"}, {id: 2, b: "b2"}, {id: 3, c: "c3"}]>
<cfset a3 = ArrayOfStructsMerge(a1, a2, "id")>