Passing Json from action to view by ViewBag - json

I'm trying to get the result below using JsonResult, but I can't
var localJSON = [
{ "id": "1", "label": "tagName1", "value": "tagValue1" },
{ "id": "2", "label": "tagName2", "value": "tagValue2" },
{ "id": "3", "label": "tagName3", "value": "tagValue3" },
{ "id": "1553", "label": "tagName1553", "value": "tagValue1553" }
];
Here is the way I use:
controller
private JsonResult GetAvailableTags()
{
var tagsList = Facade.Tags.Get(CurrentLocale.ID);
var retValue = new
{
id = tagsList.Select(x => x.ID).ToArray(),
label = tagsList.Select(x => x.Name).ToArray(),
value = tagsList.Select(x => x.Name).ToArray()
};
return Json(retValue);
}
public ActionResult AddPhoto()
{
var availblableTags = GetAvailableTags();
JavaScriptSerializer serializer = new JavaScriptSerializer();
ViewBag.AvailableTags = serializer.Serialize(availblableTags.Data);
return View();
}
view
var localJSON = [ #Html.Raw(ViewBag.AvailableTags)];
The result is
var localJSON = [
{"id":[1,2,3,1553],"label":["tagName1","tagName2","tagName3","tagName1553" ],"value":["tagName1","tagName2","tagName3","tagName1553" ]}
];
What should I do to resolve that?

I assume you want to get x.Value for value in JSON? Then change your assignment for retValue to
var retValue = tagsList.Select(
x => new
{
id = x.Id,
label = x.Name,
value = x.Value
}).ToArray();
In your retValue assignment code you were creating a single object of anonymous type with array-typed members id, label and value. For the output you want you need to create an array, each member of which is an object with simple fields id, name and value.

Related

List as Json encoding returns Last index value

here i have added the value to the contactList.listChild but the the string list doesn't return all the value to the parent list it only returns the last added value. i know its a simple mistake though i couldn't figure out where am making mistake.
any suggestion would be helpful.
ContactName contactList = new ContactName();
createJson(){
for(int index = 0; index < _contacts.length; index++){
Contact contact = _contacts?.elementAt(index);
List<Item> numbersList = contact.phones.toList();
for(int i = 0; i < numbersList.length; i++ ){
contactList.listChild = [numbersList[i].value];
}
contactList.name = contact.displayName;
lisJson.add(contactList.toJson());
}
var data = {
"data" : lisJson
};
var body = json.encode(data);
print("$body");
}
// here is my model class
class ContactName extends Object {
String name;
List<String> listChild = new List<String>();
Map toJson() => {"name":name, "phone":listChild};
}
this is what am getting from this
{
"data": [
{
"name": "user1",
"phone": [
"8221551458"
]
},
{
"name": "user2",
"phone": [
"1234567890"
]
}
]
}
// and the output should be something like this
{
"data": [
{
"name": "user1",
"phone": [
"8221551458"
]
},
{
"name": "user2",
"phone": [
"8220780548"
"1234567890"
]
}
]
}
You need to replace
contactList.listChild = [numbersList[i].value]
by
contactList.listChild.add(numbersList[i].value)
Your code is creating a new list on every iteration of the for statement, that's why the last element is the only one you see.
Be sure to initialize contactList.listChild before using it or will throw an exception when trying to add a new element.

Acumatica - Add Required Attribute to new Case through Rest API

I am trying to create new Acumatica cases through the REST API. There is an attribute on the cases that I am trying to populate. I created a Detail object for the case attributes like this.
Case Attributes
I then tried to populate a test case using the below code.
public async Task CreateTestCase()
{
Case newCase = new Case
{
ClassID = new JsonObject<string> { value = this.DepartmentToClassID["1"] },
DateReported = new JsonObject<DateTime> { value = DateTime.Now },
BusinessAccount = new JsonObject<string> { value = this.UserOrganizationToBusinessAccount["67"] },
LastActivityDate = new JsonObject<DateTime> { value = DateTime.Now },
Owner = new JsonObject<string> { value = this.OwnerToEmployee["43"] },
ClosingDate = new JsonObject<DateTime?> { value = null },
Severity = new JsonObject<string> { value = this.PriorityToSeverity["1"] },
Status = new JsonObject<string> { value = this.Status["1"] },
Subject = new JsonObject<string> { value = "Test Case" },
Attributes = new List<CaseAttribute>
{
new CaseAttribute
{
AttributeID = new JsonObject<string> { value = "Kayako Ticket Number" },
Value = new JsonObject<string> { value = "12345" }
}
}
};
var json = JsonConvert.SerializeObject(newCase);
try
{
var response = await _httpClient.PutAsync("Custom/1.0/Case", new StringContent(json, Encoding.UTF8, "application/json"));
string res = await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return;
}
}
JsonObject just adds the { "value": } object that Acumatica requires. Here is the JSON string that results from the above code.
{
"ClassID": {
"value": "SUPPORT"
},
"Contact": null,
"DateReported": {
"value": "2017-07-10T00:41:45.045008-07:00"
},
"BusinessAccount": {
"value": "24SEVEN"
},
"LastActivityDate": {
"value": "2017-07-10T00:41:45.045008-07:00"
},
"Owner": {
"value": "JSS"
},
"ClosingDate": {
"value": null
},
"Severity": {
"value": "Medium"
},
"Status": {
"value": "Open"
},
"Subject": {
"value": "Test Case"
},
"Attributes": [{
"AttributeID": {
"value": "Kayako Ticket Number"
},
"Value": {
"value": "12345"
}
}]
}
This matches the case object when I run a GET. The response that comes back is "500 Internal Server Error" and there are two errors:
CR Error: There are empty required attributes: 'Kayako Ticket Number'
Case.Attributes[1].Value: 'Kayako Ticket Number' cannot be empty.
When I create the attribute, it is created at index 0. The error indicates it is looking at index 1. Is there a way for me to load the attribute based on the attribute string and not the index number? Is it possible the attribute is not even being loaded at all?
I also tried using the KAYAKONUMB_Attributes dynamic field to load the entry. The GET successfully returned the following:
"KayakoTicketNumber": {
"value": "12002"
},
The PUT, however, returned the first error above, but not the second one. My JSON string matched the GET response.
Update
Following Serg's advice, I extended the default endpoint, and now I am able to load two of the three attributes I have. The last attribute I am trying to load is a combo box. It seems like there needs to be a different way to load that particular attribute.
Here is my current endpoint setup:
And here is my new object initializer:
Case newCase = new Case
{
ClassID = new JsonObject<string> { value = this.DepartmentToClassID["3"] },
Contact = new JsonObject<int> { value = 22322 },
DateReported = new JsonObject<DateTime> { value = DateTime.Now },
BusinessAccount = new JsonObject<string> { value = this.UserOrganizationToBusinessAccount["218"] },
LastActivityDate = new JsonObject<DateTime> { value = DateTime.Now },
Owner = new JsonObject<string> { value = this.OwnerToEmployee["43"] },
ClosingDate = new JsonObject<DateTime?> { value = null },
Severity = new JsonObject<string> { value = this.PriorityToSeverity["1"] },
Status = new JsonObject<string> { value = this.Status["1"] },
Subject = new JsonObject<string> { value = "Test Case" },
Attributes = new List<CaseAttribute<string>>
{
new CaseAttribute<string>
{
AttributeID = new JsonObject<string> { value = "Kayako Ticket Number" },
Value = new JsonObject<string> { value = "12345" }
},
new CaseAttribute<string>
{
AttributeID = new JsonObject<string> { value = "Case Reply Due Date" },
Value = new JsonObject<string> { value = "2010-10-30 00:00:00.000" }
},
new CaseAttribute<string>
{
AttributeID = new JsonObject<string> { value = "Upgrade Stage" },
Value = new JsonObject<string> { value = "7. Test In Progress"}
}
}
};
The error message being returned is:
PX.Data.PXException: CR Error: There are empty required attributes: 'Upgrade Stage'
Any help would be greatly appreciated, thank you.
I was able to solve the issue by creating a linked object and setting the attribute that way. Here is the endpoint setup (sorry for the linked images, my rep is still too low):
Linked Entity
And here is the code for creating the case object. I may need to tweak the endpoint and the objects as currently it is linking to an array of attributes but returning only the first one. I am hoping there is a way to return individual attributes.
Case newCase = new Case
{
ClassID = new JsonObject<string> { value = this.DepartmentToClassID["1"] },
Contact = new JsonObject<int> { value = 22322 },
DateReported = new JsonObject<DateTime> { value = DateTime.Now },
BusinessAccount = new JsonObject<string> { value = this.UserOrganizationToBusinessAccount["218"] },
LastActivityDate = new JsonObject<DateTime> { value = DateTime.Now },
Owner = new JsonObject<string> { value = this.OwnerToEmployee["43"] },
ClosingDate = new JsonObject<DateTime?> { value = null },
Severity = new JsonObject<string> { value = this.PriorityToSeverity["1"] },
Status = new JsonObject<string> { value = this.Status["1"] },
Subject = new JsonObject<string> { value = "Test Case" },
KayakoTicket = new CaseAttribute
{
AttributeID = new JsonObject<string> { value = "Kayako Ticket Number" },
Value = new JsonObject<int> { value = 12345 }
}
};
Finally, here is a screenshot of the case in Acumatica.
Created Case
Unfortunately, attributes are a special case (always). From what I see, you've mapped your own CaseAttribute object for this - and, unfortunately, this won't work without special actions. Try using AttributeValue entity from Acumatica's Default endpoint (and, of course, make sure that your endpoint extends Default), that might help you.

Not reading the second data from json

I am trying to read data from json (2 cycles) and add an entry. the first time, the data added successfully but during the second cycle, it failed. below are the details. Also working when run with page object and without reading from json;
The "test_pom_fromjson" added successfully but when running for the test_pom_fromjson_first it failed with error saying no element found using element(by.id('s2id_autogen10')).click(); which is the locator for location column.
Refer the screenshot and html code for the page - https://pastebin.com/ZXyRx1tv
mo.ts: pageobject for the below spec file
var mo = function () {
this.createbutton = function () {
var createb = element(by.css('button[title="Add Master Obligation"]'))
//var createbutton = element(by.buttonText('↵ ↵ Add Master Obligatio...↵ '))
browser.executeScript("arguments[0].scrollIntoView();arguments[1].click();", createb, createb);
}
this.MasterObligationName = function (value) {
element(by.model('obligation.ObligationName')).sendKeys(value);
}
this.Module = function (value) {
element(by.id('s2id_TaxProcess')).click();
element.all(by.repeater('item in obligation.TaxProcess.list')).get(value).click();
}
this.Location = function (value) {
element(by.id('s2id_autogen10')).click();
element.all(by.repeater('item in obligation.Jurisdiction.list')).get(value).click();
}
this.CentralObligation = function (value) {
element.all(by.model('obligation.CentralObligation')).get(value).click();
}
this.Type = function (value) {
element(by.id('s2id_txtReturnType')).click();
element.all(by.repeater('item in obligation.ReturnType.list')).get(value).click();
}
this.Years = function (value) {
element(by.id('s2id_txtTaxYear')).click();
element.all(by.repeater('item in obligation.TaxYears.list')).get(value).click();
}
this.Periods = function (value) {
element(by.id('s2id_txtPeriod')).click();
element.all(by.repeater('tem in obligation.Periods.list')).get(value).click();
}
this.Forms = function (value) {
element.all(by.id('s2id_txtForms')).get(0).click();
element.all(by.repeater('item in obligation.Forms.list')).get(value).click();
}
this.Reports = function (value) {
element.all(by.id('s2id_txtForms')).get(1).click();
element.all(by.repeater('item in obligation.Reports.list')).get(value).click();
}
this.savebutton = function () {
var saveb = element(by.css('button[title="Save"]'))
browser.executeScript("arguments[0].scrollIntoView();arguments[1].click();", saveb, saveb);
}
module.exports = new mo();
spec.ts: var mo = require("../page/mo.ts")
var testData = require('../testdata/testdata.json');
testData.forEach(function (data) {
it('create and save master obligation', function () {
browser.sleep(10000);
mo.createbutton();
browser.sleep(10000);
mo.MasterObligationName(data.Master_Obligation_Name)
mo.Module(data.Module);
mo.Location(data.Location);
mo.CentralObligation(data.Central_Obligation);
mo.Type(data.Type);
mo.Years(data.Years);
mo.Periods(data.Periods);
mo.Forms(data.Forms);
mo.Reports(data.Reports);
mo.savebutton();
})
})
testdata.json:
[{
"Master_Obligation_Name": "test_pom_fromjson",
"Module": "2",
"Location": "1",
"Central_Obligation": "0",
"Type": "2",
"Years": "1",
"Periods": "1",
"Forms": "1",
"Reports": "0"
},
{
"Master_Obligation_Name": "test_pom_fromjson_first",
"Module": "2",
"Location": "1",
"Central_Obligation": "0",
"Type": "2",
"Years": "1",
"Periods": "1",
"Forms": "1",
"Reports": "0"
}]
Two options you can try:
1.Wait for some time before that click
2.Either id number is auto generated so it might be changed everytime, so use some other locator.
If the id is auto-generated then look for some other locator then:
element.all(by.id('s2id_Jurisdiction')).get(1).click();
element.all(by.repeater('item in obligation.Jurisdiction.list')).get(value).click();
OR you can also try the following way:
var module = element(by.xpath("//input[starts-with(#id, 's2id_autogen')]")).get(1).click();
var location= element(by.xpath("//input[starts-with(#id, 's2id_autogen')]")).get(2).click();
var type = element(by.xpath("//input[starts-with(#id, 's2id_autogen')]")).get(3).click();

how to convert json tree to table, and back(same table to json tree)

i need to convert json tree to table, and back(same table to json tree), PostgreSQL
example:
{
"id": 1,
"title": "Example Node(UnDeleteable, and no counted)",
"items": [
{
"id": 2,
"title": "dfsdfs",
"items": [
{
"id": 3,
"title": "dfsfddfsfd",
"items": [
{
"id": 4,
"title": "dsffdsdfsfdsdfs",
"items": [
{
"id": 5,
"title": "dfsdsfdfsddfs",
"items": []
}
]
}
]
}
]
}
]
}
]
need to be:
ParentId ChildId title
NULL 1 "Example Node(UnDeleteable, and no counted)"
1 2 "dfsdfs"
2 3 "dfsfddfsfd"
etc
....
...
...
someone can help me with that? Thanks!
I think all you need is a two-dimensional array and recursion.
here is my code about tanslating a json to a tree. I think it is easy to feed your needs with a little modification.
var jsonTreeServ = {};
jsonTreeServ.toTreeJson = function (jsonObj, treeArr) {
for (var k in jsonObj) {
var val = jsonObj[k];
if (val instanceof Object) {
var node = {};
node.title = k;
node.value = '';
node.visible = true;
node.nodes = [];
treeArr.push(node);
jsonTreeServ.toTreeJson(val, node.nodes);
} else {
var node = {};
node.title = k;
if(null!==val && ''!==val){
node.title += '=';
val = jsonTreeServ.translateTimestamp(node.title, val);
}
node.value = val;
node.visible = true;
treeArr.push(node);
}
}
return treeArr;
}

Json response + Node.js

In my node app i pass bunch of queries as Object.I have to form as exact format of request.
Consider my request as:
{q0:{query0},q1:{query1},q2:{query1}}
My reponse should be {q0:{response0},q1{response1},q2{response2}
My actual query(In my app):
{"q0":{"query":"James Madison","type":"/people/presidents","type_strict":"should"},
"q1":{"query":"George Washington","type":"/people/presidents","type_strict":"should"},
"q2":{"query":"John Adams","type":"/people/presidents","type_strict":"should"},
"q3":{"query":"James Monroe","type":"/people/presidents","type_strict":"should"},
"q4":{"query":"Thomas Jefferson","type":"/people/presidents","type_strict":"should"}}
But my response is coming as:
{"result":[q0result,q1result,q3result]}
My code:
for (var id in presidents ) {
var match
if (query == presidents[id]) {
//console.log(" Inside match")
match = true;
}
else {
match = false;
}
matches.push({
"id": id,
//"name": name,
"score": 100,
"match": match,
"type": [{
"id": "/people/presidents",
"name": "US President"
}]
})
}
callback(matches);
json = JSON.stringify({"result":matches});
res.writeHead(200, {'content-type':'application/json'});
res.end(json);
Please help me to solve this..Thanks in advance.
You are pushing the result in an array instead you should create a property in the result object as below
var matches = {};
for (var id in presidents ) {
if (query == presidents[id]) {
//console.log(" Inside match")
match = true;
}
else {
match = false;
}
matches[id] ={
"id": id,
//"name": name,
"score": 100,
"match": match,
"type": [{
"id": "/people/presidents",
"name": "US President"
}]
};
}
callback(matches);