I'm new to this LWC and im trying to get the data be displayed in a data table tree grid
where i used a wrapper class together with my Apex Class.
i cant seem to find the problem as the data wont show in the table..
im able to see in the console so just putting it in the table is what im trying to do..
Below is my Html
<template>
<lightning-card title="Skills Tree">
<lightning-tree-grid
key-field="Id"
columns={columns}
data={skillList}
hide-checkbox-column
></lightning-tree-grid>
</lightning-card>
</template>
Javascript
import { LightningElement, wire, track, api } from "lwc";
import getSkillsInventory from "#salesforce/apex/dataTableClass.getSkillsInventory";
export default class DataTableTreeGrid extends LightningElement {
error;
#track skillList;
#track expandedRows = [];
#track wiredskillListData;
#track contactId;
#api recordId;
#wire(getSkillsInventory, { contactId: "$recordId" })
wiredskillListData(result) {
if(result.data){
console.log('this is data')
console.log(result.data)
this.skillList = result.data;
}else if(result.error){
console.log('error # ' + result.error);
}
}
constructor() {
super();
this.columns = [
{
type: "text",
fieldName: "skillName",
label: "Skills Name",
_children: [
{
type: "text",
fieldName: "subskills",
}
],
},
{
type: "text",
fieldName: "skillProficiency",
//fieldName: "Name",
label: "Proficiency"
},
{ type: "action", typeAttributes: { rowActions: this.getRowActions } }
];
}
get expandedRowItems() {
return this.expandedRows;
}
getRowActions(row, doneCallback) {
const actions = [];
actions.push({
label: "Edit",
name: "edit"
});
actions.push({
label: "Delete",
name: "delete"
});
doneCallback(actions);
}
}
WRAPPER CLASS;
public class SkillMatrixWrapper {
#AuraEnabled
public List<SkillL1> skillInfoList {get;set;}
public class SkillDetails{
#AuraEnabled
public String skillName {get;set;}
#AuraEnabled
public String skillProficiency {get;set;}
}
public class SkillL3{
#AuraEnabled
public SkillDetails skillInfo {get;set;}
}
public class SkillL2{
#AuraEnabled
public SkillDetails skillInfo {get;set;}
#AuraEnabled
public List<SkillL3> subskills {get;set;}
}
public class SkillL1{
#AuraEnabled
public SkillDetails skillInfo {get;set;}
#AuraEnabled
public List<SkillL2> subskills {get;set;}
public SkillL1(SkillDetails skillInfoDetails){
skillInfo = skillInfoDetails;
subskills = new List<SkillL2>{};
}
}
}
Related
here is my codes.
json_model
var mix = {
MixName: $("#mixname").val(),
MixDesc: tinyMCE.activeEditor.getContent(),
Price: $("#price").val(),
DiseaseMixs: [],
MixProducts: []
}
Add items to DiseaseMixs and MixProducts
$("#DiseaseList").find("tbody tr").each(function (index) {
mix.DiseaseMixs.push({
MixID: parseInt(MixID),
DiseaseID: parseInt($(".diseaseid").eq(index).html()),
ImpactDegree: parseInt($(".derece option:selected").eq(index).html()),
Description: $(".diseaseMixDesc input").eq(index).val()
});
})
$("#productList").find("tbody tr").each(function (index) {
mix.MixProducts.push({
MixID: parseInt(MixID),
ProductID: parseInt($(".productid").eq(index).html()),
MeasureTypeID: parseInt($(".birim option:selected").eq(index).val()),
MeasureAmount: $(".measureAmount input").eq(index).val()
});
})
and end of this process, here is a sample json object that is post.
{
"MixName": "asdasddas",
"MixDesc": "<p>sadasd</p>",
"Price": "123",
"DiseaseMixs": [{
"MixID": 1,
"DiseaseID": 2,
"ImpactDegree": 5,
"Description": "asads"
}, {
"MixID": 1,
"DiseaseID": 3,
"ImpactDegree": 4,
"Description": "aqqq"
}],
"MixProducts": [{
"MixID": 1,
"ProductID": 2,
"MeasureTypeID": 3,
"MeasureAmount": "3"
}, {
"MixID": 1,
"ProductID": 3,
"MeasureTypeID": 2,
"MeasureAmount": "45"
}]
}
ajax post
$.ajax({
url: 'SaveMix',
type: 'POST',
data: JSON.stringify(mix),
contentType: 'application/json; charset=utf-8',
success: function (result) {
console.log(result);
},
error: function (xhr, status) {
alert(status);
console.log(xhr);
}
})
and MVC Model and JSONResult function
Model
public class MixModel
{
public string MixName { get; set; }
public string MixDesc { get; set; }
public float Price { get; set; }
DiseaseMix[] DiseaseMixs { get; set; } //DiseaseMix EntityFramework entity
MixProduct[] MixProducts { get; set; } //MixProduct EF
}
function
[HttpPost]
public JsonResult SaveMix(MixModel mix)
{
bool result = false;
//do something
return Json(new { result = result }, JsonRequestBehavior.AllowGet);
}
and here is the result I get is.
No matter how I tried, I could not bind the model.
What am I doing wrong? Please give me some help.
Thanks in advance.
Model binding is failing because those 2 properties are currently private(which is the default when you don't specify anything explicitly).
Change the 2 properties to public so that model binder can set the values of those.
public class MixModel
{
public string MixName { get; set; }
public string MixDesc { get; set; }
public float Price { get; set; }
public DiseaseMix[] DiseaseMixs { get; set; } //DiseaseMix EntityFramework entity
public MixProduct[] MixProducts { get; set; } //MixProduct EF
}
I also suggests to not mix your view models with entities generated by your ORM. That creates a tightly coupled solution.
Currently I am using Typewriter for automatic generation of TypeScript class from my C# classes. Lets say I have this very simple C# class:
[Dto]
public class MyDto
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}
Also I have this simple typewriter template:
$Classes(c => c.Attributes.Any(x => x.Name == "Dto"))[
export class $Name {
constructor(
$Properties[
public $name: string,
]
) { }
}]
The issue I have with this template is that there is a trailing comma after the last constructor parameter property in the generated ts class:
export class MyDto {
constructor(
public prop1: string,
public prop2: string, /* <---- notice the comma here */
) { }
}
I would like to have the properties of the C# class generated as parameter properties in the TypeScript class, but with the example above the generated TypeScript is not valid. Is there a way to achieve this with a Typewriter template?
To answer my own question: I amended the template like this:
$Classes(c => c.Attributes.Any(x => x.Name == "Dto"))[
export class $Name {
constructor(
$Properties[
public $name: string][,]
) { }
}]
Client code:
var basket = {
products: [],
user: { name: "schugh" }
};
$("#basket table tr").each(function (index, item) {
var product = $(item).data('product');
if (product) {
basket.products.push(product);
}
});
$.ajax({
url: "http://localhost:12116/basketrequest/1",
async: true,
cache: false,
type: 'POST',
data: JSON.stringify(basket),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (result) {
alert(result);
},
error: function (jqXHR, exception) {
alert(exception);
}
});
Server code:
Post["/basketrequest/{id}"] = parameters =>
{
var basketRequest = this.Bind(); //basketrequest is null
return Response.AsJson(basketRequest , HttpStatusCode.OK);
};
Other model classes:
[Serializable]
public class BasketRequest
{
public User User;
public List<Product> Products;
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
public ProductStatus ProductStatus { get; set; }
}
public enum ProductStatus
{
Created,
CheckedBy,
Published
}
public class User
{
public string Name { get; set; }
}
The code in the Nancy Module this.Bind(); returns null. If I change the Complex object to just List<Product>, i.e. with no wrapper BasketRequest, the object is fine...
Any pointers?
EDIT: JSON posted:
{
"User": {
"Name": "SChugh"
},
"Products": [{
"Id": 1,
"Name": "Tomato Soup",
"Category": "Groceries",
"Price": 1
}, {
"Id": 2,
"Name": "Yo-yo",
"Category": "Toys",
"Price": 3.75
}]
}
Your BasketRequest object should implement properties instead of fields. So
public class BasketRequest
{
public User User { get; set; }
public List<Product> Products { get; set; }
}
also you should probably use the generic method too
this.Bind<BasketRequest>();
I'm trying to save new item to my database using Breeze and web api.
Here is my model:
public class MuscleGroup
{
#region Properties
public int MuscleGroupId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string ImageUrl { get; set; }
#endregion
#region Navigational properties
public virtual ICollection<Muscle> Muscles { get; set; }
public virtual ICollection<Exercise> Exercises { get; set; }
#endregion
}
Here is my API:
[BreezeController]
public class MuscleGroupController : ApiController
{
private readonly EFContextProvider<MadBarzDatabaseContext> _contextProvider =
new EFContextProvider<MadBarzDatabaseContext>();
// GET api/<controller>
[HttpGet]
public IQueryable<MuscleGroup> Get()
{
return _contextProvider.Context.MuscleGroups;
}
[HttpPost]
public SaveResult SaveChanges(JObject saveBundle)
{
return _contextProvider.SaveChanges(saveBundle);
}
}
Here are parts of my dataService.js:
app.angularModule.service('muscleGroupService', function(breeze, logger) {
breeze.config.initializeAdapterInstance("modelLibrary", "backingStore", true);
var mbservice = new breeze.DataService({
serviceName: "http://localhost:23758/api/MuscleGroup",
hasServerMetadata: false,
});
var manager = new breeze.EntityManager({ dataService: mbservice });
manager.enableSaveQueuing(true);
var removeItem = breeze.core.arrayRemoveItem;
var items = [];
var muscleGroupService =
{
getAll: getAll,
getSucceeded: getSucceeded,
getFailed : getFailed,
addItem: addItem,
// deleteItem: deleteItem,
// updateItem : updateItem,
};
return muscleGroupService;
//#region addItem
function addItem(initialValues) {
var item = manager.createEntity("MuscleGroup", initialValues);
saveChanges().fail(addFailed);
items.push(item);
return item;
function addFailed() {
removeItem(items, item);
}
}
//#endregion
//#region SaveChanges
function saveChanges() {
return manager.saveChanges()
.then(saveSucceeded)
.fail(saveFailed);
}
function saveSucceeded(saveResult) {
logger.success("Saved :D");
logger.log(saveResult);
}
function saveFailed(error) {
logger.error(error);
logger.log(error);
}
//#endregion
}
Here is part of my controller:
$scope.addNewItem = function() {
var newItem = muscleGroupService.addItem({ Id: 42, Name: $scope.Name, Description: "ho", ImageUrl: "hey"});
$scope.items.push(newItem);
};
And this is error I get:
Error: Unable to locate a 'Type' by the name: 'MuscleGroup'. Be sure to execute a query or call fetchMetadata first.
at proto._getEntityType (http://localhost:7122/Scripts/breeze.debug.js:6056:19)
at proto.getEntityType (http://localhost:7122/Scripts/breeze.debug.js:6047:21)
at Object.addItem (http://localhost:7122/Scripts/app/AdminMuscleGroup/MuscleGroupService.js:61:45)
at Object.$scope.addNewItem (http://localhost:7122/Scripts/app/AdminMuscleGroup/MuscleGroupController.js:16:42)
at http://localhost:7122/Scripts/angular/angular.js:6365:19
at http://localhost:7122/Scripts/angular/angular.js:12987:13
at Object.Scope.$eval (http://localhost:7122/Scripts/angular/angular.js:8057:28)
at Object.Scope.$apply (http://localhost:7122/Scripts/angular/angular.js:8137:23)
at HTMLButtonElement.<anonymous> (http://localhost:7122/Scripts/angular/angular.js:12986:17)
at HTMLButtonElement.jQuery.event.dispatch (http://localhost:7122/Scripts/jquery-1.8.2.js:3063:9) angular.js:5754
I query All Muslce groups before I try to add antoher.
PW Kad is giving you the clues.
When you wrote hasServerMetadata: false, you told Breeze not to get metadata from the server; you told Breeze that you would provide the metadata on the client. You aren't providing metadata on the client.
You're controller doesn't have a Metadata endpoint ... and couldn't offer such an endpoint AND ALSO be structured as the controller-per-type API controller that you seem determined to devise.
You're deviating from the standard Breeze productivity path while pursuing controller-per-type. That's fine ... after you have a little experience, know what you're doing, and know why you're doing it. The hasServerMetadata flag is true by default for a reason; you can't just set it false and expect everything to work.
I suggest that you back up, follow the Breeze guidance, understand it, then depart from that guidance incrementally as you discover solid, business reasons for doing so.
I'm trying to build a treepanel (or just a simple tree I just need it to work) and load it with data from database
I've been trying and trying and trying ..but cant do it.
Can someone show me how can I do this please?
My JSON:
{
{Title:'yahoo Website',adress:'www.yahoo.com',Description:'Serveur yahoo'},
{Title:'skype',adress:'skype.com',Description:'skype.com'},
{Title:'bing',adress:'www.bing.com',Description:'microsoft bing'},
{Title:'facebook',adress:'www.facebook.com',Description:'social network'},
{Title:'Google',adress:'Google.com',Description:'Google';},
{Title:'\' or 1=1--',adress:'\' or 1=1--',Description:'\' or 1=1--'}
]
My C# code:
public class Interact : JsonRpcHandler {
[JsonRpcMethod()]
public string ReadAssets() {
clsDBInteract objDBInteract = new clsDBInteract();
string result;
try {
result = objDBInteract.FetchAssetsJSON();
} catch (Exception ex) {
throw ex;
}
return result;
}
firstly look at this simple example. This tree have a store wich can read infromation from url by json scructure. You can write there http://youdomain.com/yourscript.php. At yourscript.php you have to read information from database, encode it to JSON and run echo your_json;
That's all.
P.S. json example
i solved this by creating my own type (no jayrock)
my tree model and store:
Ext.define('TreeModel', {
extend: 'Ext.data.Model',
fields: [
{ name: 'text' },
{ name: 'id' },
{ name: 'descr' }
]
});
window.TreeStore = Ext.create('Ext.data.TreeStore', {
model: 'TreeModel',
root: Ext.decode(obj.TreeToJson()),
proxy: {
type: 'ajax'
},
sorters: [{
property: 'leaf',
direction: 'ASC'
}, {
property: 'text',
direction: 'ASC'
}]
});
my class:
public class TreeItem
{
public string text { get; set; }
public int id { get; set; }
public string descr { get; set; }
public string expanded { get; set; }
public string leaf { get; set; }
public List<TreeItem> children { get; set; }
}
then i get my data and fill my tree like this
public string TreeToJson()
{
List<TreeItem> child = new List<TreeItem>();
for (int i = 0; i < n; i++)
{
child.Add(new TreeItem() { text = t.AssetTree()[i].Item1, id = t.AssetTree()[i].Item2, ip = t.AssetTree()[i].Item3, descr = t.AssetTree()[i].Item4, expanded = "false", leaf = "true" });
}
TreeItem tree = new TreeItem() { text = "my root", id = 0, expanded = "true", leaf = "false", children = child };
}
hope it helps someone