Angular 2 correct way to get data from server - forms

I want to get data from the database. I'm following the examples at angular.io webpage but I don't know if I'm doing right.
I have a form and when a user fills the postal code field, I call the database to get the name of the city or, if it doesn't exist, ask the user to fill it.
My problem is I don't know how to correctly do it.
In my service.
checkCp(city: City): Observable<any> {
return this.http.get<any>(this.backendUrl + 'api/city/' + city.cp).pipe(
tap(city => console.log("fetched"))
);
}
and this is in my component.js
checkCp(): void {
this.modal.header = 'Searching city';
this.modal.text = 'Please wait';
this.openWaitModal();
this.studentService.checkCp(this.city)
.subscribe(cityFromDb => {
if(cityFromDb ===null) {
this.closeWaitModal();
this.modal.header = 'Postal code not found';
this.modal.text = 'Insert the name of the city';
this.modal.no = 'Cancel';
this.modal.yes = 'Insert';
this.modal.action = 'newCity';
this.modal.enableInput = true;
this.openModal();
}else{
this.closeWaitModal();
this.city = cityFromDb.city; // I can't access cityFromDb.name
// i access via cityFromDb.city.name
}
}, err => {
this.errorHandler(err);
})
}

You would call your service as follows:
checkCp(city: City): Observable<any> {
return this.http.get<any>(this.backendUrl + 'api/city/' + city.cp);
};
This will return an Observable to your component.ts
The code in your component.ts should work now

Related

Cesium too much recursion error on using CallbackProperty to fetch entity description

The entities are updated multiple times in a second. I want to fetch description details at each position and using callback property. The same code is working if I return time or any constant value but gives too much recursion error when I return the description of the entity.
viewer.selectedEntityChanged.addEventListener(function(selectedEntity) {
if (Cesium.defined(selectedEntity)) {
if (Cesium.defined(selectedEntity.description)) {
console.log('Selected ' + selectedEntity.id);
selectedEntity.description = new Cesium.CallbackProperty(function(time) {
var currentDescription = selectedEntity.description.getValue(time);
console.log(currentDescription);
return currentDescription;
// return time;
}, false);
} else {
console.log('Unknown entity selected.');
}
} else {
console.log('Deselected.');
}
});

Flutter add multiple value into map

So I'm trying to create a flutter app. In my app user A can invite user B,C and so on to join the group, but the user invited can reject the ticket. The user ID that reject the ticket will be stored in the firestore to detect which id reject it and there's a reason why.
The database data looks like this:
- Rejected_detail_map
----Rejected_role_admin
-------- USER_ID_A : "REASON_TO_REJECT"
-------- USER_ID_C : "REASON_TO_REJECT"
----Rejected_role_member
-------- User_ID_B :"REASON_TO_REJECT_2"
I wanted to fetch the data from each rejected_detail_map in one of my page, and use that ID to get the information such as nickname, prof_pic, etc.
Here's how I do it:
if (data['reject_detail_map'] != null) {
if (data['reject_detail_map'].isNotEmpty) {
List rejectDetailKeyList = data['reject_detail_map'].keys.toList();
if (rejectDetailKeyList.contains('rejected_by_pic')) {
List picIdRejectList = data['reject_detail_map']['rejected_by_pic'].keys.toList();
Map picRejectData = {};
await Future.forEach(picIdRejectList, (picId) async {
try {
if (Provider.of<OtherUserDataProvider>(context, listen: false)
.getUserData(picId.toString()) ==
null) {
picRejectData[picId] = await UserDatabase.getUserShortData(userId: picId.toString(), context: context);
Provider.of<OtherUserDataProvider>(context, listen: false).setUserData(userInfo: picRejectData[picId], userId: picId.toString());
picRejectData[picId]['role'] = 'pic';
picRejectData[picId]['reject_text'] = data['reject_detail_map']['rejected_by_pic'][picId];
ticketData['user_reject_data'] = Map.of(picRejectData);
} else {
picRejectData[picId] = Map.of(Provider.of<OtherUserDataProvider>(context, listen: false).getUserData(picId.toString())!);
picRejectData[picId]['role'] = 'pic';
picRejectData[picId]['reject_text'] = data['reject_detail_map']['rejected_by_pic'][picId];
ticketData['user_reject_data'] = Map.of(picRejectData);
}
} catch (e) {
DevMode.log("Error: $e");
}
});
}
if (rejectDetailKeyList.contains('rejected_by_client')) {
List clientIdRejectList = data['reject_detail_map']['rejected_by_client'].keys.toList();
Map clientRejectData = {};
await Future.forEach(clientIdRejectList, (clientId) async {
try {
if (Provider.of<OtherUserDataProvider>(context, listen: false)
.getUserData(clientId.toString()) ==
null) {
clientRejectData[clientId] = await UserDatabase.getUserShortData(userId: clientId.toString(), context: context);
Provider.of<OtherUserDataProvider>(context, listen: false).setUserData(userInfo: clientRejectData[clientId], userId: clientId.toString());
clientRejectData[clientId]['role'] = 'client';
clientRejectData[clientId]['reject_text'] = data['reject_detail_map']['rejected_by_client'][clientId];
ticketData['user_reject_data'] = Map.of(clientRejectData);
} else {
clientRejectData[clientId] = Map.of(
Provider.of<OtherUserDataProvider>(context, listen: false)
.getUserData(clientId.toString())!);
clientRejectData[clientId]['role'] = 'client';
clientRejectData[clientId]['reject_text'] = data['reject_detail_map']['rejected_by_client'][clientId];
ticketData['user_reject_data'] = Map.of(clientRejectData);
}
} catch (e) {
DevMode.log("Error: $e");
}
});
}
}
}
The problem is the ticketData['user_reject_data'] is always limited to 1 person, like the data from before next id is overwritten. So if there are 2 person rejecting the invitation:
User A reject as admin
User B reject as member
the data that i expect to be shown when printing the 'user_reject_data' are:
user_reject_data{
"user_A" : {his info}
"user_B" : {his info}
}
but i will always get only the user B data, like the user A is being over written. I guess there's something wrong with the way I add the data to the map. How to fix this ?

Email multiple cells to recipient instead of one email per cell using Apps Script

Currently I'm working on a script that checks values of one column and based on that send email containing information from another column. Everything works perfectly except one thing - it send one email per value and I'd like to send all the values in one email. Can someone please help with the issue ?
const helpsheet = SpreadsheetApp.openById("ID").getSheetByName('Sheet');
const date = helpsheet.getRange(1,10).getValue();
const ss = SpreadsheetApp.openById("ID2");
const sh = ss.getSheetByName('Sheet2');
const data = sh.getRange('A2:c'+sh.getLastRow()).getValues();
var recipients = 'EMAIL#EMAIL';
var subject = 'SUBJECT';
data.forEach(r=>{
let overdueValue = r[2];
if (overdueValue > date)
{
let path = r[0];
MailApp.sendEmail({
to: recipients,
subject: subject,
htmlBody: 'Hi guys ' + path +'!<br><br>Best regards,'
});
}
});
} ```
Of course I can't test this because 1st I don't want a bunch of emails to myself and 2nd I don't have a data set that matches your data, but I'm pretty sure this will do what you want. What I do is build an array of rows that pass the sniff test using the Array push method below. Then when I have all the rows that pass I send one email.
I have edited this post to include functions to create an html table.
function test() {
try {
const helpsheet = SpreadsheetApp.openById("ID").getSheetByName('Sheet');
const date = helpsheet.getRange(1,10).getValue();
const ss = SpreadsheetApp.openById("ID2");
const sh = ss.getSheetByName('Sheet2');
const data = sh.getRange('A2:c'+sh.getLastRow()).getValues();
var pre = "Hello";
var post = "Best regards";
var recipients = 'EMAIL#EMAIL';
var subject = 'SUBJECT';
var passed = [];
data.forEach( r => {
let overdueValue = r[2];
if (overdueValue > date) {
passed.push(r);
}
});
if( passed.length > 0 ) { // maybe nothing passed the test
var html = createHTMLfile(true);
html = html.concat("<p>"+pre+"</p>");
html = html.concat(createTable(passed));
html = html.concat(createHTMLfile());
html = html.concat("<p>"+post+"</p>");
MailApp.sendEmail( {
to: email,
subject: subject,
htmlBody: html });
};
}
}
catch(err) {
console.log(err);
}
}
I have added the additional functions to create the table. You are welcome to play with the <style>s.
function createHTMLfile(pre) {
if( pre ) {
return "<html><head><style>table, td { border: thin solid black; border-collapse:collapse; text-align:center }</style></head><body>";
}
else {
return "</body></html>";
}
}
function createTable(data) {
try {
var width = 600/data[0].length;
var table = "<table>";
function addCell(value) {
table = table.concat("<td style=width:"+width+"px>");
table = table.concat(value.toString());
table = table.concat("</td>");
}
function addRow(row) {
table = table.concat("<tr>");
row.forEach( addCell );
table = table.concat("</tr>");
}
data.forEach( addRow )
table = table.concat("</table>");
return table;
}
catch(err) {
console.log(err);
}
}

Handling concurrency exceptions when passing the objects ids and timestamps using jQuery

I have the following business scenario inside my Asp.net MVC 4 asset management system :-
Scenario 1) A user selects multiple servers , then he selects a Rack Tag ,and click on
assign . so the selected servers will be assigned to the new Rack.
Scenario 2) And i want to check for any concurrency exception , if for example the selected
servers have been modified by another user since they were retrieved .
so i have wrote the following jQuery which will send the object ids+timestamps to the action method:-
$('body').on("click", "#transferSelectedAssets", function () {
var boxData = [];
$("input[name='CheckBoxSelection']:checked").each(function () {
boxData.push($(this).val());
});
var URL = "#Url.Content("~/Server/TransferSelectedServers")";
$.ajax({
type: "POST",
url: URL,
data: { ids: boxData.join(","), rackTo: $("#rackIDTo").val()}
,
success: function (data) {
addserver(data); })});
and inside the action method i have the following code:-
public ActionResult TransferSelectedServers(string ids, int? rackTo)
{
if (ModelState.IsValid)
{
try
{
var serverIDs = ids.Split(',');
int i = 0;
foreach (var serverinfo in serverIDs)
{
var split = serverinfo.Split('~');
var name = split[0];
//System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] bytearray = Encoding.Default.GetBytes(split[1]);
i++;
var server = repository.FindServer_JTechnology(Int32.Parse(name));
if (server == null)
return Json(new { IsSuccess = false, reload = true, description = " Some Servers might have been deleted, Transferre process has been cancelled .", rackid = rackFrom }, JsonRequestBehavior.AllowGet);
server.RackID = rackTo;
server.timestamp = bytearray;
string ADusername = User.Identity.Name.Substring(User.Identity.Name.IndexOf("\\") + 1);
repository.InsertOrUpdateServer(server, ADusername, server.Technology.IT360ID.Value, server.IT360SiteID, new bool(), server.Technology);
}
repository.Save();
return Json(new { IsSuccess = true, description = i + " Server/s Transferred Successfully To Rack " + }, JsonRequestBehavior.AllowGet);
}
catch (DbUpdateConcurrencyException e)
{
return Json(new { IsSuccess = false, reload = true, description = "records has been modified by antoehr user" }, JsonRequestBehavior.AllowGet);
}
catch (Exception e)
{
return Json(new { IsSuccess = false, reload = true, description = " Server/s Can not Be Transferred to the Selected Rack " }, JsonRequestBehavior.AllowGet);
}
}
return RedirectToAction("Details", new { id = rackTo });
}
and the repository method looks as follow:-
public void InsertOrUpdateServer(TMSServer server, string username, long assetid, long? siteid = 0, bool isTDMHW = false, Technology t = null)
{
server.IT360SiteID = siteid.Value;
tms.Entry(server).State = EntityState.Modified;
var technology = tms.Technologies.Single(a => a.TechnologyID == server.TMSServerID);
technology.IsManaged = t.IsManaged;
tms.Entry(technology).State = EntityState.Modified;
InsertOrUpdateTechnologyAudit(auditinfo);
}
}
but currently if two users selects the same servers and assign them to tow different racks , no concurrency exception will be raised ?
Can anyone advice ? baring in mind that if two users edit single object then one of them will get an concurrent exception message. so my timestamp column is defined correctly.
Thanks

set user id based on pk when logged in through facebook

I am able to login/logout on my web app using facebook. But the problem is when the user needs to update his profile on my application, he can't. It would say that he is restricted to view his own page. The only way for this to happen is that user identity is probably not set. But I am not sure how to correct this. When I tried Yii::app()->user->user_id the Id is actually correct id, which is the pk in user model. So how is it that he cannot get to update his own page?
in my facebookUserIdentity:
public function authenticate()
{
if($this->getIsAccessTokenValid() && $this->setFBUser())
{
$this->_user = $this->getUserFromDatabase();
if($this->_user === false)
return false;
$this->setState('isUser', false);
$this->setState('isAdmin', false);
$this->setState('isShop', false);
$this->setState('isSuper', false);
$this->setState('user',$this->_user);
$this->_id = $this->_FBUser['id'];
//I've tried doing something like $this->_id = Yii::app()->user->user_id; or like $this->_user->user_id; ?
$this->_name = $this->_FBUser['name'];
return true;
}
else {
return false;
}
}
getting user from db:
protected function getUserFromDatabase()
{
$FBUser = $this->_FBUser;
if($FBUser)
{
$user = User::model()->findByAttributes (array('oauth_uid'=>$FBUser['id']));
if(!$user)
{
$user = new User;
$user->oauth_uid = $FBUser['id'];
$user->username = $FBUser['id'];
$user->first_name = $FBUser['first_name'];
//other info etc
$user->image = "https://graph.facebook.com/" . $FBUser['id'] . "/picture?type=large";
}
else
{
if ($user->oauth_permission == 'n')
{
$this->errorMessage = self::ERROR_LOGIN_DISABLE;
return false;
}
$user->last_login_date = date('Y-m-d H:i:s');
}
if($user->save())
{
return $user;
}
else
$this->errorMessage = CJSON::encode ( $user->getErrors());
return false;
}
else {
$this->errorMessage = "Failed getting facebook user data";
return false;
}
}
and lastly, the controller page rules:
public function accessRules()
{
$params=array();
$id=Yii::app()->request->getParam('id');
$params['model']=$this->loadModel($id);
return array(
//stuff
array('allow', // allow authenticated user to perform 'create' and 'update' actions
'actions'=>array('create','update','RemoveImage'),
'roles'=>array('admin','super','owner'=>$params),
),
//stuff