Angular UI-Grid Pivot - angularjs

I have a collection of these Javascript objects: (Displayed as a DTO)
public class ParameterValueDTO : DataTransferObject
{
public int Id { get; set; }
public String Comments { get; set; }
public String Description { get; set; }
}
By default, AngularJS UI-Grid will create a row for each ParameterValue object with 3 columns: Id, Comments, Description which works fine.
IMAGE: Standard objects mapping to table
What I would like to do however is create a column for each object's "Comments" value and bind it to the corresponding "Description" value. Essentially pivoting the table so it only has 1 row (forget the ID column for now).
The javascript I've tried:
var cols = [];
var row = obj.data.ProductAttributes[0].Specifications[0].ParameterValues
var length = row.length;
for (var i = 0; i < length; i++) {
cols.push({
field: "Description",
displayName: row[i].Comments
});
}
$scope.gridOptions = {
columnDefs: cols,
data: row
};
The above results in the following which is obviously wrong:
IMAGE: One column, new row for each Description
Is it possible to accomplish this with the current data structure or what exactly is the correct approach I should be taking?

I'd modify the code to just reprocess your data. ui-grid really only likes to bind to columns and rows, it can't reverse the order.
So you'd:
var pivotData = [ {} ];
data.forEach(function(parameterDTO) {
pivotData[0][parameterDTO.comments] = parameterDTO.description;
});
Then you should be able to use that new data object as grid data.

Related

How can I update a TextField value and have its associated index in an array update as well?

I am having trouble updating values in an array that are displayed via a for each loop. These values are displayed in a text field.
The code in question
struct EditItemView: View {
let entity: RecipeEntity
#StateObject var viewModel = ViewModelEdit()
#State var imageToUpload: Data
#StateObject var vm = CoreDataRelationshipViewModel()
#Environment(\.presentationMode) var presentationMode
#State var stepInfo: String = ""
#State var textFieldCount: Int = 1
#State var stepNumber: [Int]
#State var recipeName: String = ""
#State var recipeArray: [RecipeStepModel]
var body: some View {
//some code between here and the problem code
List {
ForEach(recipeArray, id: \.id) { index in
HStack {
CustomTextField(item: index)
}
}.onDelete { (indexSet) in
recipeArray.remove(atOffsets: indexSet)
}
CustomTextField I am using that allows me to pass my Identifiable model into a foreach. This can be seen referenced in the for each above as CustomTextField(item: index)
struct CustomTextField : View {
#State var item : RecipeStepModel
var body : some View {
Text(String(item.stepNumber) + ".")
TextField("", text: $item.stepName)
}
}
Lastly, here is the model for the array referenced in the last #State variable declared #State var recipeArray: [RecipeStepModel]:
struct RecipeStepModel: Identifiable {
var id = UUID()
var stepName: String
var stepNumber: Int
}
The Question
How can I make a change to a textfield in a foreach loop and have its value in #State var recipeArray: [RecipeStepModel] be updated accordingly? For example, I edit the first TextField in the for each loop - how can I update index 0 in the array with its new value?
Additional Information
I posted a similar question the other day. I was able to get it working with .indices in the for each loop. The version of the question asked here is an attempt at restructuring my code using MVVM. Previous question and answer can be found here - I hope this helps!
You need to follow a architecture like MVVM. Make a model where you have your struct RecipeStepModel and then make a seperate ViewModel to add and delete recipes in your array. You should study the Combine framework in SwiftUI, it is used to get input from textfield and then store it in an array.
Check this tutorial from Peter Freise https://github.com/peterfriese/MakeItSo/tree/firebase-combine/final/MakeItSo/MakeItSo for reference.
I ended up solving the issue by converting #State var item: RecipeStepModel in my view model to #Binding var item: RecipeStepModel
struct CustomTextField : View {
#Binding var item : RecipeStepModel
var body : some View {
Text(String(item.stepNumber) + ".")
TextField("", text: $item.stepName)
}
Once this change was made, I had to alter the code in my ForEach to pass a binding to the CustomTextField view model. Additionally, I had to change ForEach(recipeArray, id: \.id) to ForEach(recipeArray.indices, id: \.self) :
List {
ForEach(recipeArray.indices, id: \.self) { index in
HStack {
CustomTextField(item: $recipeArray[index]) //<--change made here
}
}.onDelete { (indexSet) in
recipeArray.remove(atOffsets: indexSet)
}
I am now able to both successfully delete items from the list, and update items in the array simply by changing the value in the appropriate TextField

How set id via Exposed

I create object and dao class for work with sql
object UserTable : IdTable<Int>("User") {
val parameters = reference("search_parameters_id", SearchParametersTable)
override val id = integer("id").entityId()
override val primaryKey = PrimaryKey(id)
}
class User(id: EntityID<Int>) : Entity<Int>(id) {
companion object : EntityClass<Int, User>(UserTable)
var searchParameters by SearchParameters referencedOn UserTable.parameters
}
But I cann't set id, beacause id is val
Do you mean that you want to insert a record with an arbitrary id
value? If yes, you can write like below.
val newId = 10
User.new(newId) {
// set values to other columns
}

$http post from angularjs to C# MVC view model, have correct List count but the values are null

I have the following post request using $http
var registration = {
userId: 23,
groupings: [
{ Id: 1, Name: 'Test Group 1', Description: 'Yo' },
{ Id: 4, Name: 'Test Group 4', Description: 'Er' }
]
}
$http({
method: 'POST',
url: url,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: $.param({
code: eventCode,
UserId: registration.userId
Groupings: registration.groupings
})
})
And then on my action
[HttpPost]
public ActionResult New(string code, RegistrationVM model)
{
:
:
:
}
public class RegistrationVM
{
public int UserId {get;set;}
public IEnumerable<GroupingVM> Groupings { get; set; }
}
public class GroupingVM{
public int Id {get;set;}
public string Name {get;set;}
public string Description {get;set;}
public int AnotherPropertyId {get;set;}
public ANewClass ANewClass {get;set;}
}
Whenever the post happens, I would have the model properties reflect what I posted except the IEnumerable (Groupings) property. Let's say I post with 2 objects on the Groupings property, when I go to the Action, the Groupings property will have a count of 2 but every instance would have either NULL or 0 values on each object. I'm trying to figure out how I'm messing the post.
First, make the controller take one object as a parameter. Add the "string code" to the RegistrationVM and remove the string code as a parameter.
Then do the same when you create the client object.
Secondly, instead of using the content type "x-www-form-urlencoded" use the "application/json" which is better suited to pass objects.
Before posting the data you need to stringify the obj with data: JSON.stringify(registration)
For more details, read the comments on the question.

LINQ : filter multiple string values - partial match - not full match as in multiple online examples

There are many good examples of searching multiple string values in LINQ e.g.
public static Product[] GetProducts(Guid[] prodIDs)
{
return (from p in GetProducts()
where prodIDs.Contains(p.ProductID)
select p).ToArray<Product>();
}
I have a list of Products that I need to match from a customer,
but I dont have an exact match - the Customers List Of Products contains my ProductID - but it is not exact - e.g.
Customer MyCompany
Description Description
Prod1XY Prod1
AProd2B Prod2
XXXProd3 Prod3
I thus cannot filter from the prodIDs [string array] because Prod1 does not contain Prod1XY
and thus cannot use the examples that are available.
How can I effectively change (reverse) the working examples
as to search CustomerProducts where it contains my Product Description please?
So to confirm : this is not a duplicate. The examples use the string[] x
input parameter and then searches:
where x.contains
I need help to get it : myProducts.Contains(x)
another online example modified to show the situation:
static void Main(string[] args) {
var table = new[] {
new { uid = 1 },
new { uid = 2 },
new { uid = 3 },
new { uid = 4 },
new { uid = 5 }
};
var stringarray = new[] { "1", "5", "10" };
var results = from xx in table
where table.Contains(stringarray)
select xx;
foreach (var result in results) {
Console.WriteLine("Result: " + result.uid.ToString());
}
}
It is not clear enough what you are trying to accomplish, but under assumption that you want to select all products where ProductID contains any value from specified list, it looks like that it:
public static Product[] GetProducts(string[] prodIDs)
{
return (from p in GetProducts()
where prodIDs.Any(id=>p.ProductID.Contains(id))
select p).ToArray<Product>();
}
Try this
public static Product[] GetProducts(string[] prodIDs)
{
return (
from p in GetProducts()
from q in prodIDs
where p.ProductID.IndexOf(q) > -1
select p)
.ToArray<Product>();
}

UpdateOperations embedded array

I have an structure like this:
{
_id: 123,
bs: [
{
_id: 234,
cs: [
{
_id: 456,
ds : [
{
_id: 678,
emails[
"email#gmail.com"
]
}
]
}
]
}
]
}
My classes in Morphia seems like this
#Entity
public class A {
#Id
private ObjectId id;
#Embedded
private List<B> bs;
}
public class B {
private ObjectId id;
#Embedded
private List<C> cs;
}
public class C {
private ObjectId id;
#Embedded
private List<D> ds;
}
public class D {
private ObjectId id;
#Embedded
private List<String> emails;
}
What I am trying to do is insert an email inside embedded array with Morphia without retrieve all element A and use updateFirst.
This is the query I am trying execute
Query<Event> query = this.basicDAO.createQuery();
query.criteria(Mapper.ID_KEY).equal(new ObjectId(aID));
query.criteria("bs.cs.id").equal(new ObjectId(cID));
query.criteria("bs.cs.ds.id").equal(dID);
UpdateOperations<Event> updateOps = this.basicDAO.createUpdateOperations().set("bs.cs.ds.$.emails", email);
this.basicDAO.update(query, updateOps);
I also read about this post Update an item in an array that is in an array with said that
$ operator does not work "with queries that traverse nested arrays".
So I tried something like:
D d = new D(dID);
C c = new C(new ObjectId(cID));
Query<Event> query = this.basicDAO.createQuery();
query.criteria(Mapper.ID_KEY).equal(new ObjectId(aID));
query.field("bs.cs").hasThisElement(c);
query.field("bs.cs.ds").hasThisElement(d);
UpdateOperations<Event> updateOps = this.basicDAO.createUpdateOperations().set("bs.cs.ds.emails", email);
this.basicDAO.update(query, updateOps);
However it still doesn't work. Any idea how solve this? The error message that I receive is cannot use the part ... to transverse the element
Based on your stand-in use case, I think you should "invert" your schema. Each document will represent a lecture and will be tagged with its theme, edition, and event:
{
"_id" : ObjectId("54da1ff0a9ce603a239c3075"),
"event" : "X0004",
"edition" : "A0002,
"theme" : "RT0005",
"votes" : 22
}
event, edition, and theme can be some kind of identifiers, and might be references to event, edition, and theme documents in other collections. To cast a vote for a particular lecture, just update it by _id:
db.test.update({ "_id" : ObjectId("54da1ff0a9ce603a239c3075") }, { "$inc" : { "votes" : 1 } })
While I don't know your full requirements, I think this is a better basic design given your example use case.

Resources