Here's the call that works with my API, but I need to render the result in leaf. This currently works fine with the API. Just not sure how where I'm grabbing the teams.
func getTeamsWithUsersForEvent(_ req: Request) throws -> Future<[TeamWithUsers]> {
let currentID = try req.parameters.next(Int.self)
print("currentID \(currentID)")
return Team.query(on: req).filter(\Team.eventID == currentID).sort(\Team.rawScore, .descending).range(..<5).all().flatMap(to: [TeamWithUsers].self) { team in
try team.map { team in
try team.users.query(on: req).all().map { users in
var score: Int
if users.isEmpty {
score = 0
}else{
score = team.rawScore / users.count
}
return TeamWithUsers(
id: team.id,
name: team.name,
icon: team.icon,
eventID: team.eventID,
rawScore: team.rawScore,
//users: users,
count: users.count,
teamScore: score
// teamScore: team.rawScore / users.count
)
}
}.flatten(on: req)
}
}
struct TeamWithUsers: Content {
let id: Int?
let name: String
let icon: String
let eventID: Event.ID
let rawScore: Int
//let users: [User]
let count: Int?
let teamScore: Int
}
Here's the what I've started. This is my context.
struct AllTeamsContext: Encodable {
let title: String
let teams: [TeamWithUsers]
}
And I've created the Leaf template called "Leaders" which just shows a table with TeamWithUsers per row.
#if(count(teams) > 0) {
<table class="table table-bordered table-hover">
<thead class="thead-light">
<tr>
<th>Name</th>
<th>Icon</th>
<th>Score</th>
</tr>
</thead>
<tbody>
#for(team in teams) {
<tr>
<td>#(team.name)</td>
<td>#(team.icon)</td>
<td>#(team.teamScore)</td>
</tr>
}
</tbody>
</table>
} else {
<h2>There aren’t any teams yet.</h2>
}
EDIT: changed answer in the light of the additional information in the comments.
Whilst you could change your existing function to return the view directly, I personally would leave it as-is and call it from a second that renders the view. Try putting this in the same router as your current function:
func teamsView(_ req: Request) throws -> Future<View> {
let currentID = try req.parameters.next(Int.self)
let teamsContext = getTeamsWithUsersForEvent(request, currentID)
return request.view().render("Leaders", teamsContext )
}
Then, in your routes.swift or equivalent, put:
router.grouped("admin","teams") teamsRoute.get("leaders", Int.parameter, use: teamsView)
Move the parameter into the tsamsview function above and then you need to modify your original function header to be:
func getTeamsWithUsersForEvent(_ req: Request, _ currentID:Int) throws -> Future<[TeamWithUsers]>
Then remove your original parameter extraction from this function.
As your router is grouped your view should be visible on:
http://localhost:8080/admin/teams/nnn/leaders
where nnn is what will get translated into currentID.
ALTERNATIVELY:
If this is getting a bit messy (and in spite of my first comment about preferring to keep the functions separate), you could always alter your existing function to:
func getTeamsWithUsersForEvent(_ req: Request) throws -> Future<View> {
let currentID = try req.parameters.next(Int.self)
print("currentID \(currentID)")
let teamContext = Team.query(on: req).filter(\Team.eventID == currentID).sort(\Team.rawScore, .descending).range(..<5).all().flatMap(to: [TeamWithUsers].self) { team in
try team.map { team in
try team.users.query(on: req).all().map { users in
var score: Int
if users.isEmpty {
score = 0
} else {
score = team.rawScore / users.count
}
return TeamWithUsers(
id: team.id,
name: team.name,
icon: team.icon,
eventID: team.eventID,
rawScore: team.rawScore,
//users: users,
count: users.count,
teamScore: score
)
}
}.flatten(on: req)
}
return request.view().render("Leaders", teamContext )
}
Related
I have a collection with chatroom information. Something like this:
{
chatroomid: 59,
members: [2,3]
}
Now what I want to do is, get the collection stream, in the course of doing that be able to replace the members string ids with a corresponding firestore document based on member id.
End result should look something like this:
{
chatroomid: 59,
members: [{
id: 2,
username: Johndoe1
},
{
id: 3,
username: Jennydoe1
}]
}
Is this possible with Dart RxDart?
Trying something like this fails:
getChatroomStream(chatroomid)
.switchMap((i) {
return Stream.value(i.members.map((e) => i.members.add(Document(path: 'Global.userRef/$e').streamData())));
})
.listen((event) {print(event);});
[VERBOSE-2:ui_dart_state.cc(177)] Unhandled Exception: Concurrent
modification during iteration: Instance of
'MappedListIterable<dynamic, void>'.
#0 ListIterator.moveNext (dart:_internal/iterable.dart:337:7)
class MemberInfo {
final int id;
final String? username;
final bool isLoading;
}
class Room {
final int chatroomid;
final List<int> members;
}
class RoomWithMemberInfos {
final int chatroomid;
final List<MemberInfo> infos;
factory RoomWithMemberInfos.initial(Room room) {
return RoomWithMemberInfos(
room.chatroomid,
room.members
.map((id) => MemberInfo(id, null, true))
.toList(growable: false)
);
}
RoomWithMemberInfos withInfo(MemberInfo info) {
return RoomWithMemberInfos(
chatroomid,
infos
.map((e) => e.id == info.id ? MemberInfo(e.id, info.name, false) : e)
.toList(growable: false)
);
}
}
Stream<MemberInfo> getMemberInfo(int id) { ... }
getChatroomStream()
.switchMap((Room room) {
final initial = RoomWithMemberInfos.initial(room);
return Stream
.fromIterable(room.members)
.flatMap(getMemberInfo)
.scan<RoomWithMemberInfos>(
(acc, info) => acc!.withInfo(info),
initial,
)
.startWith(initial);
});
i am creating simple sales system for my final year project. i am creating a sales Form. attached the screen shot image below how the form look like.
after sales completed i need to save the data into multiple table along with the lastinsert id. if i click print invoice button. i have a tables in the database sales,sales product i shown the shot shotimage below.i don't how to save records into multipule table with lastinsert id.
enter image description here
Sales Table
id date subtotal
Sales_Product Table
id sales_id product_id price qty total
Code which i tried
jQuery
function addProject() {
var table_data = [];
$('#product_list tbody tr').each(function (row, tr) {
var sub = {
//these records i am going to add into sales table
'barcode': $(tr).find('td:eq(1)').text(),
'pname': $(tr).find('td:eq(2)').text(),
'pro_price': $(tr).find('td:eq(3)').text(),
'qty': $(tr).find('td:eq(4)').text(),
'total_cost': $(tr).find('td:eq(5)').text(),
};
table_data.push(sub);
});
//these records i am going to add into sales
var total = $("#total").val();
$.ajax({
type: 'POST',
url: '/product/Save',
dataType: 'JSON',
data: {
total: $('#total').val(), data: table_data
},
success: function (data) {
console.log(_data);
var msg;
if (isNew) {
msg = "Sales Completed";
}
last_id = data.last_id
window.location.href = "print.php?last_id=" + last_id;
$.alert({
title: 'Success!',
content: msg,
type: 'green',
boxWidth: '400px',
theme: 'light',
useBootstrap: false,
autoClose: 'ok|2000'
});
isNew = true;
},
error: function (xhr, status, error) {
alert(xhr);
}
});
}
Controller
[HttpPost]
public ActionResult Save(sale s)
{
bool status = false;
if (ModelState.IsValid)
{
using (saleEntities3 dc = new saleEntities3())
{
//Sales table
var v = dc.sales.Where(a => a.id == s.id).FirstOrDefault();
dc.sales.Add(v);
dc.SaveChanges();
v.id = s.id; // lastinsertid
//how to add into lastinsertid as a sales product table as a sales_id colum
//Sales product table i don't how to add
status = true;
}
}
return new JsonResult { Data = new { status = status } };
}
saleEntities3
public partial class saleEntities3 : DbContext
{
public saleEntities3()
: base("name=saleEntities3")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<product> products { get; set; }
public virtual DbSet<sale> sales { get; set; }
public virtual DbSet<sales_product> sales_product { get; set; }
}
}
To save in the Sales_Product table you need to save with the id of the saved sales according to your table structure
[HttpPost]
public ActionResult Save(sale s)
{
bool status = false;
if (ModelState.IsValid)
{
using (saleEntities3 dc = new saleEntities3())
{
//Sales table
var v = dc.sales.Where(a => a.id == s.id).FirstOrDefault();
dc.sales.Add(v);
dc.SaveChanges();
dc.sales_product.Add(new sales_product{
sales_id = s.id,
product_id = s.barcode, //I believe this is the product id
price = s.pro_price,
quantity = s.qty,
total = s.total_cost
});
dc.SaveChanges();
status = true;
}
}
return new JsonResult { Data = new { status = status } };
}
I am sending data from view to controller using ajax , modelID , catId etc and searching data from database against these parameters, but first time load session values but after that if i change its value cant not load session values.
$("#ModelID").change(function () {
var Cat = $("#Cat").val();
var subcat = $("#CatID").val();
if (Cat != "" & subcat != "") {
$("#modalvalag").modal("show");
$.ajax({
type: 'post',
url: '/Inventory/CatSubCatAgainstModal',
data: {
Cat: $("#Cat").val(),
SubCat: $("#CatID").val(),
ModelID: $("#ModelID").val()
},
success: function (response) {
$('#noo').html(response);
}
});
}
else {
alert("Please select Category Or sub category to complete this process");
}
return false
});
Here is controller code:
public ActionResult CatSubCatAgainstModal(int Cat = 0, int SubCat = 0 , int ModelID = 0)
{
// var dta = db.ItemsCatSubCats.Where(m => m.CatID == CatID & m.SubCatID == SubCatID).FirstOrDefault();
//Session["ItemName"] = dta.Category.Catgory + "|" + dta.SubCategory.SubCat;
Session["CatID"] = Cat;
Session["SubCat"] = SubCat;
Session["ModelID"] = ModelID;
var data = db.ItemAttributes.Where(m => m.CatID == Cat & m.SubCatID == SubCat & m.ModelID == ModelID).ToList();
int c = 0;
foreach(var itm in data){
Session["value"+c] = itm.AttributeValue;
c++;
}
return RedirectToAction("AttributListForValue");
}
I'm trying to write additional properties to the log using {Properties} (which are not in the message template):
Used (FileSink) template:
"[{Level}] {Message}{NewLine}{Properties}{NewLine}{Exception}"
Log operation (simplified, normally the object array is given by a method parameter):
Log.Information("Start logging",
new object[]{
new { Version = "VersionString"},
new { StartDate = DateTime.Now },
new { Id = Guid.NewGuid() }
});
I also tired:
Log.Information("Start logging",
new object[]{
"VersionString",
DateTime.Now,
Guid.NewGuid()
});
I had a look on LogEventPropertyCapturingTests and this PR, but I couldn't get it working...
Update
I use wrapper functions like this:
public static void Information(string messageTemplate, object[] propertyValues, bool show = false, [CallerMemberName] string callerMethodeName = "", [CallerFilePath] string callerFilePath = "", [CallerLineNumber] int callerLineNumer = -1)
{
using (LogContext.PushProperty("CallingContext", new { callerMethodeName, callerFilePath, callerLineNumer }))
{
_MainLog.Information(messageTemplate, propertyValues);
}
if(show)
{
// Code to show a the event to the user
}
}
Update2 Found a way but it's not very nice, as the template-property-matching rudimentary.
public static void Information(string messageTemplate, object[] propertyValues, bool show = false, [CallerMemberName] string callerMethodeName = "", [CallerFilePath] string callerFilePath = "", [CallerLineNumber] int callerLineNumer = -1)
{
using (LogContext.PushProperty("CallingContext", new { callerMethodeName, callerFilePath, callerLineNumer }))
{
Regex matchProperties = new Regex("{[^}]+}");
int usedPropertiesCount = matchProperties.Matches(messageTemplate).Cast<Match>().Select(m => m.Value).Distinct().Count();
if (propertyValues.Length > usedPropertiesCount)
{
using (LogContext.PushProperty("AdditionalData", propertyValues.Skip(usedPropertiesCount)))
{
_MainLog.Information(messageTemplate, propertyValues);
}
}
else
{
_MainLog.Information(messageTemplate, propertyValues);
}
}
if(show)
{
// Code to show a the event to the user
}
}
The ForContext() method will do this:
Log.ForContext("Version", "VersionString")
.ForContext("Id", Guid.NewGuid())
.Information("Start logging");
(I've omitted StartDate because all Serilog events are already timestamped.)
This blog post series includes some posts on message templates plus context and correlation that cover this plus other alternatives.
I have mvc 5 and EF6 and never really use async in mvc before so want ask best way for run sql requests.
public ActionResult SearchTest(string id)
{
string searchtxt = UsefulClass.ConvertObjectToString(id).Replace(",", " ").Trim();
var model = new SearchResult();
if (!String.IsNullOrEmpty(searchtxt))
{
//get the data from 3 requests
var ArtistList = _db.Artists.SqlQuery("SELECT top 6 * FROM Artists WHERE CONTAINS(Name, N'Queen') and TopTracksStatus = 1 and GrabStatus > 1 order by playcount desc").ToList();
var tracks = _db.Database.SqlQuery<TrackInfo>("exec SearchTracks #SearchText=N'Queen', #TopCount=10,#LengthCount=100").ToList();
var TagsList = _db.Tags.Where(x => x.TagName.Contains(searchtxt)).Take(5).ToList();
//work with ArtistList and add to model
if (ArtistList.Any())
{
int i = 0;
foreach (var artist in ArtistList)
{
i++;
if (i == 1) //top artist
{
model.BestArtist = artist;
model.BestArtistTrackCount = _db.TopTracks.Count(x => x.Artist_Id == artist.Id);
}
else
{
model.ArtistList = ArtistList.Where(x => x.Id != model.BestArtist.Id);
break;
}
}
}
//work with tracks and add to model
if (tracks.Any())
{
model.TopTrackList = tracks;
}
//work with tags and add to model
if (TagsList.Any())
{
model.TagList = TagsList;
}
}
return View(model);
}
Here I have 3 requests which return ArtistList, tracks, TagsList and I need add them to model and then pass to view. How to do it in async way?
Try below example, hope it gives you a good idea.
public async Task<ActionResult> SearchTestAsync(string id)
{
string searchtxt = UsefulClass.ConvertObjectToString(id).Replace(",", " ").Trim();
var model = new SearchResult();
if (!String.IsNullOrEmpty(searchtxt))
{
var art = GetArtistListResulst(model);
var track = GetTracksResults(model);
var tag = GetTagsListResults(model,searchtxt);
await Task.WhenAll(art, track, tag);
}
return View(model);
}
private Task GetArtistListResulst(SearchResult model)
{
return Task.Run(() =>
{
var artistList = _db.Artists.SqlQuery("SELECT top 6 * FROM Artists WHERE CONTAINS(Name, N'Queen') and TopTracksStatus = 1 and GrabStatus > 1 order by playcount desc").ToList();
// You don't need to use foreach because the artistList is ordered by playcount already.
model.BestArtist = artistList.Take(1);
model.BestArtistTrackCount = _db.TopTracks.Count(x => x.Artist_Id == model.BestArtist.Id);
model.ArtistList = artistList.Where(x => x.Id != model.BestArtist.Id);
});
}
private Task GetTracksResults(SearchResult model)
{
return Task.Run(() =>
{
model.TopTrackList = _db.Database.SqlQuery<TrackInfo>("exec SearchTracks #SearchText=N'Queen', #TopCount=10,#LengthCount=100").ToList();
});
}
private Task GetTagsListResults(SearchResult model, string searchtxt)
{
return Task.Run(() =>
{
model.TagsList = _db.Tags.Where(x => x.TagName.Contains(searchtxt)).Take(5).ToList();
});
}