Accessing Item Fields via Sitecore Web Service - sitecore

I am creating items on the fly via Sitecore Web Service. So far I can create the items from this function:
AddFromTemplate
And I also tried this link: http://blog.hansmelis.be/2012/05/29/sitecore-web-service-pitfalls/
But I am finding it hard to access the fields. So far here is my code:
public void CreateItemInSitecore(string getDayGuid, Oracle.DataAccess.Client.OracleDataReader reader)
{
if (getDayGuid != null)
{
var sitecoreService = new EverBankCMS.VisualSitecoreService();
var addItem = sitecoreService.AddFromTemplate(getDayGuid, templateIdRTT, "Testing", database, myCred);
var getChildren = sitecoreService.GetChildren(getDayGuid, database, myCred);
for (int i = 0; i < getChildren.ChildNodes.Count; i++)
{
if (getChildren.ChildNodes[i].InnerText.ToString() == "Testing")
{
var getItem = sitecoreService.GetItemFields(getChildren.ChildNodes[i].Attributes[0].Value, "en", "1", true, database, myCred);
string p = getChildren.ChildNodes[i].Attributes[0].Value;
}
}
}
}
So as you can see I am creating an Item and I want to access the Fields for that item.
I thought that GetItemFields will give me some value, but finding it hard to get it. Any clue?

My advice would be to not use the VSS (Visual Sitecore Service), but write your own service specifically for the thing you want it to do.
This way is usually more efficient because you can do exactly the thing you want, directly inside the service, instead of making a lot of calls to the VSS and handle your logic on the clientside.
For me, this has always been a better solution than using the VSS.

I am assuming you are looking to find out what the fields looks like and what the field IDs are.
You can call GetXml with the ID, it returns the item and all the versions and fields set in it, it won't show fields you haven't set.

Related

Retrieve item from db using ObjectMapper

I'm totally new to coding in general, so this is really my first attempt, so don't shoot me if I ask stupid questions ;) Right now I'm having trouble even understanding the the vast world of backend.
So I'm having some problems in my service, and even deciding which way is the best to go, scanning, querying... what?
So I -think- the way to go for me is scanning... I'm having trouble to retrieve an item from the database, based on the id of that item. Retrieving all items works like a charm, and I need something similar for getting one item. I'm getting confused when searching the web, and not really even understanding the difference for example scanfilter, scanexpression? That's why I haven't even come up with a good attempt... but what I need is scan the table and retrieve the item with the matching id. I tried looking at my method for retrieving all searchCases, and implement it for retrieving one it, as it should look quite the same, but no success...
EDITED method a bit: Method I need help with:
public SearchCase getSearchCase(String id){
//this is obviously for a list, but how do I do it for ONE item?
HashMap<String, AttributeValue> sc = new HashMap<String, AttributeValue>();
sc.put("scId", new AttributeValue().withS(id));
ScanRequest scanRequest = new ScanRequest()
.withTableName(searchCaseTableName)
.withFilterExpression("id = scId");
ScanResult scanResult = client.scan(scanRequest);
?????
return searchCase;
}
As a reference here is the method for retrieving all items, that does work:
public List<SearchCase> getSearchCases() {
final List<SearchCase> cases = new ArrayList<SearchCase>();
ScanRequest scanRequest = new ScanRequest()
.withTableName(searchCaseTableName);
ScanResult result = client.scan(scanRequest);
try {
for (Map<String, AttributeValue> item : result.getItems()) {
SearchCase searchCase = mapper.readValue(item.get("payload").getS(), SearchCase.class);
cases.add(searchCase);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return cases;
}
It has been forever, but thought I'd post the correct answer I fought with for a long time back in June. So this was the solution that worked for me for retrieving a single item:
public SearchCase getSearchCase(String id) throws Exception {
Table t = db.getTable(searchCaseTableName);
GetItemSpec gis = new GetItemSpec()
.withPrimaryKey("id", id);
Item item = t.getItem(gis);
SearchCase searchCase = mapper.readValue(StringEscapeUtils.unescapeJson(item.getJSON("payload").substring(1)), SearchCase.class);
return searchCase;
}
This method actually took a whole another approach then the way I originally thought I would solve this. So no Scanrequest, but using GetItemSpec and Item instead. This thus caused some funky backslashes in the JSON, so my frontend wouldn't accept before I ran it through StringEscapeUtils.unescapeJson, otherwise worked like a charm.
I'm having trouble to retrieve an item from the database, based on the id of that item
If you want to retrieve an item from DynamoDB based on some unique ID, then use load, which "Loads an object with the hash key given".

Increment Number Property in AWS DynamoDB

How do I increment a number in AWS Dynamodb?
The guide says when saving an item to simply resave it:
http://docs.aws.amazon.com/mobile/sdkforios/developerguide/dynamodb_om.html
However I am trying to use a counter where many users may be updating at the same time.
Other documentation has told me to use and UpdateItem operation but I cannot find a good example to do so.
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.Modifying.html
However, I cannot find a method to implement the expression. In the future I will be adding values to arrays and maps. Will this be the same? My code is in Obj C
Currently my code looks like:
AWSDynamoDBUpdateItemInput *updateItemInput = [AWSDynamoDBUpdateItemInput new];
updateItemInput.tableName = #"TableName";
updateItemInput.key = #{
UniqueItemKey:#"KeyValue"
};
updateItemInput.updateExpression = #"SET counter = counter + :val";
updateItemInput.expressionAttributeValues =#{
#":val":#1
};
It looks like you're missing the last bit of code that actually makes the update item request:
AWSDynamoDB *dynamoDB = [AWSDynamoDB defaultDynamoDB];
[[dynamoDB updateItem:updateItemInput]
continueWithBlock:^id(AWSTask *task) {
if (task.error) {
NSLog(#"The request failed. Error: [%#]", task.error);
}
if (task.exception) {
NSLog(#"The request failed. Exception: [%#]", task.exception);
}
if (task.result) {
//Do something with result.
}
return nil;
}];
In DynamoDB if you want to increment the value of the any propertie/field you can use the UpdateItemRequest with action option ADD. I used in android this method would update the existing value of the field. Let me share the code snippet. You can use any actions such like add,delete,put etc.
.....
AttributeValue viewcount = new AttributeValue().withS("100");
AttributeValueUpdate attributeValueUpdate = new AttributeValueUpdate().withAction(AttributeAction.ADD).withValue(viewcount);
updateItems.put(UploadVideoData.FIELD_VIEW_COUNT, attributeValueUpdate);
UpdateItemRequest updateItemRequest = new UpdateItemRequest().withTableName(UploadVideoData.TABLE_NAME)
.withKey(primaryKey).withAttributeUpdates(updateItems);
UpdateItemResult updateItemResult = amazonDynamoDBClient.updateItem(updateItemRequest);
....
You can see the above code will add 100 count into the existing value of that field.
This code is for android but the technique would remain the same.
Thank you.

Retrieve data from ParseUser after using FindAsync

I've created a number of users in Parse. There're Facebook users and non-Facebook user. For each Facebook user I've saved an extra column of "facebookID".
Now I'd like to get all the ParseUsers that are Facebook Users. So I applied a Task to query the users with "facebookID" in them.
var Task = ParseUser.Query.WhereExists("facebookID").FindAsync().ContinueWith(t=>{
if (t.IsFaulted || t.IsCanceled) {
Debug.Log ("t.Exception=" + t.Exception);
//cannot load friendlist
return;
}
else{
fbFriends = t.Result;
foreach(var result in fbFriends){
string id = (string)result["facebookID"];
//facebookUserIDList is a List<string>
facebookUserIDList.Add(id);
}
return;
}
});
The above code works perfectly. However, I'd like to get more data from each Facebook User, for example, the current_coins that the user has. So I change the foreach loop to:
foreach(var result in fbFriends){
string id = (string)result["facebookID"];
int coins = (int)result["current_coins"];
//facebookUserIDList is a List<string>
facebookUserIDList.Add(id);
}
I've changed the facebookUserIDList into a List<Dictionary<string,object>> instead of a List<string> in order to save the other data as well. But the foreach loop does not run at all. Does it mean I can only get the facebookID from it because I specified WhereExists("facebookID") in FindAsync()? Can anybody explain it to me please?
Thank you very much in advance.
it should contain all Parse primitive data type(such as Boolean, Number, String, Date...) for each Object. but not Pointers nor Relation.
for Pointers, you can explicitly include them in the result using the "Include" method
for any ParseRelation you have to requery them

Search Dialogs in Epicor

Hopefully someone here is familiar with creating customizations in Epicor 9. I've posted this to the Epicor forums as well, but unfortunately that forum seems pretty dead. Any help I can get would be much appreciated.
I've created a customization on the Order Entry form to display and store some extra information about our orders. One such field is the architect on the job. We store the architects in the customer table using a GroupCode of AR to distinguish them from regular customers. I have successfully added a button that launches a customer search dialog and filters the results to only display the architects (those with GroupCode AR). Here's where the problems come in. I have two questions:
1: On the customer search, there is a customer type field that defaults to a value of Customer. Other choices are < all>, Suspect, or Prospect. How can I make the search form default to < all>?
2: How do I take the architect (customer) I select through the search dialog and populate its CustID into the ShortChar01 field on my Order Entry customization? Here's the code I have:
private void SearchOnCustomerAdapterShowDialog()
{
// Wizard Generated Search Method
// You will need to call this method from another method in custom code
// For example, [Form]_Load or [Button]_Click
bool recSelected;
//string whereClause = string.Empty;
string whereClause = "GroupCode = 'AR'";
System.Data.DataSet dsCustomerAdapter = Epicor.Mfg.UI.FormFunctions.SearchFunctions.listLookup(this.oTrans, "CustomerAdapter", out recSelected, true, whereClause);
if (recSelected)
{
System.Data.DataRow adapterRow = dsCustomerAdapter.Tables[0].Rows[0];
// Map Search Fields to Application Fields
EpiDataView edvOrderHed = ((EpiDataView)(this.oTrans.EpiDataViews["OrderHed"]));
System.Data.DataRow edvOrderHedRow = edvOrderHed.CurrentDataRow;
if ((edvOrderHedRow != null))
{
edvOrderHedRow.BeginEdit();
edvOrderHedRow["ShortChar01"] = adapterRow["CustID"];
edvOrderHedRow.EndEdit();
}
}
}
When I select a record and click OK, I get an unhandled exception.
I think the problem you are/were having is that you aren't adding the CustNum to the Sales Order first. In my mind I would do it this way first, but there is might be ChangeCustomer BO method in oTrans that you could call to make sure everything defaults correct.
EpiDataView edvOrderHed = ((EpiDataView)(this.oTrans.EpiDataViews["OrderHed"]));
if (edvOrderHed.HasRow)
{
edvOrderHed[edvOrderHed.Row].BeginEdit();
edvOrderHed[edvOrderHed.Row]["CustNum"] = adapterRow["CustNum"];
edvOrderHed[edvOrderHed.Row]["ShortChar01"] = adapterRow["CustID"];
edvOrderHed[edvOrderHed.Row].EndEdit();
}
Hope that is helpful, even if late.

Multiple TemplateIds not working in Sitecore's Advanced Database Crawler

I have a "Featured" widget to lead visitors to items I want to feature on certain pages. So I'm trying to get Alex Shyba's Advanced Database Crawler for Sitecore to return all the items that refer to the context item. If I put in one template ID, it works fine. But if I pipe delimit the two templates, I never get a result. What am I doing wrong?
var searchParam = new MultiFieldSearchParam()
{
Database = Sitecore.Context.Database.Name,
Language = Sitecore.Context.Language.Name,
TemplateIds = "{E5B41848-3C07-4F17-84A5-C2C29AD43CAE}|{0C2E35D7-C4C9-478B-B4AB-DE8C2A00908B}"
};
var refinements = new List<MultiFieldSearchParam.Refinement>();
refinements.Add(new MultiFieldSearchParam.Refinement("pages", contextItemGUID));
searchParam.Refinements = refinements;
var runner = new QueryRunner("web");
foreach (var skinnyItem in runner.GetItems(searchParam))
{
yield return skinnyItem.GetItem();
}
Again, if I make that TemplateIds a single GUID (either one), it works as expected, but just returning, obviously, items of the specified template.
As Mark notes, it's a bug in the ADC. Our solution was to refactor the ApplyTemplateFilter method as follows:
protected void ApplyTemplateFilter(CombinedQuery query, string templateIds, QueryOccurance occurance)
{
ApplyIdFilter(query, BuiltinFields.Template, templateIds, occurance);
}