API using App.Data and entity relations

Jan 7, 2016 at 11:14 AM
Hi there,

I want to report a scenario, that I just had and would be pleasured to get some feedback.

App scenario:
  • 2sxc Content Types
  • Angular
First issues:
I tried to use the 2sxc content("") helper inside of my angular service, but every get(id) request was a 500, same issues in the sample app (feedback) with 8.00.11...

So I switched to using a WebAPI Controller (App.Data).

I have a ContentType "Reservation" and a ContentType "Rooms", where Rooms are selectable in Reservation as Entity.

I tried different things to make the "AsDynamic" work, here is just how it 'should' work:
var compacted = from r in reservations
                            select new
                            {
                                guid = RandomString(20),
                                Id = r.EntityId,
                                title = r.title,
                                description = r.description,
                                start = r.start,
                                end = r.end,
                                EditorUserName = r.EditorUserName,
                                EditorDisplayName = r.EditorDisplayName,
                                Modified = r.Modified,
                                IsPublished = r.IsPublished,
                                room= r.room // ?? empty
...
...
I tried different things (e.g. using AsDynamic with another linq inside the main linq), but nothing worked, room was empty [{}] or I got an error all the time.

What I now did, was the following:
public dynamic All()
    {
List<Dictionary<string, object>> ret = new List<Dictionary<string, object>>();

            var reservations = App.Data["Reservations"].List;

            foreach (KeyValuePair<int, ToSic.Eav.IEntity> kvp in reservations)
            {
                ToSic.Eav.IEntity res = kvp.Value;
                Dictionary<string, object> entry = new Dictionary<string, object>();
                entry.Add("Id", res.EntityId);
                entry.Add("title", res.GetBestValue("title"));
                entry.Add("description", res.GetBestValue("description"));
                entry.Add("start", res.GetBestValue("start"));
                entry.Add("end", res.GetBestValue("end"));
                entry.Add("EditorUserName", res.GetBestValue("EditorUserName"));
                entry.Add("EditorDisplayName", res.GetBestValue("EditorDisplayName"));

                ToSic.Eav.IAttribute roomattr = res.Attributes["room"];
                ToSic.Eav.IValue roomval = roomattr.Values.First();
                string roomguid = roomval.Serialized;

                entry.Add("room", getRoomByGuid(roomguid));

                ret.Add(entry);
            }

            return ret;
}
private Dictionary<string, object> getRoomByGuid(string _Guid)
    {
        var rooms = App.Data["Rooms"].List;
        foreach (KeyValuePair<int, ToSic.Eav.IEntity> kvp in rooms)
        {
            ToSic.Eav.IEntity ro = kvp.Value;
            if (ro.EntityGuid.ToString() == _Guid)
            {
                Dictionary<string, object> room = new Dictionary<string, object>();
                room.Add("Id", ro.EntityId);
                room.Add("title", ro.GetBestValue("title"));
                return room;
            }
        }
        return null;
    }
I had to dig into the eav to get the selected room values.
My question now is, if there is a better way approaching that.

BR, Daniel
Coordinator
Jan 11, 2016 at 1:22 PM
Wow - someone who actually reads code - awesome :)!

The EAV usually scares of most people, so I'm surprised :)

Basically with AsDynamic it should work. AsDynamic has many overloads so you can use it on both an item or a list, like
var x = AsDynamic(Content);

var x = AsDynamic(App.Data["Reservations"]); // a list of dynamic items
We always do that. So if you got an error, I'm guessing it's a linq issue (very tricky / error prone to write LINQ if you don't have 100+ hours of practice). I recommend you try 2-3 simple things to see if it works, then build on that. Maybe something like
var reservations = AsDynamic(App.Data["Reservations"]);

foreach(var res ...) {
 // try for each first using a standard property
 <li>@res.EntityId</li>
}
when you get that to work, try going function- LiNQ
var mapped = reservations.Select(x => x.EntityId).ToList();

foreach(...)
Then expand on that to create entire objects.
Jan 11, 2016 at 2:37 PM
I love (to) code, so I read code, no matter what language :)

Hm, I knew there has to be more about LINQ, have to dig into that...
swings strangers mantle around the shoulder and dissolves into the darkness :)

Schluss mit lustig :)

Thanks for the tips, have to get into LINQ now :)