Angularfire2 get a key of added object - firebase-realtime-database

Am I able to get a key of just added object?
For example:
items.push(
{ ... }
).then(_ => console.log(key of the object));

items.push(
{ ... }
).then(_ => console.log('Added item key is ', _.key));
Please try like this.

If you mean Firebase 3 (AngularFire's $firebaseArray has a $add to replace push) then it returns a reference that is also a "thenable", checkout the Firebase docs
So you can get the key of the reference even synchronously:
var thenableRef = dataRef.push({someKey: 'some value'});
var newItemKey = thenableRef.$key;
thenableRef.then(_ => console.log('There\'s my new key: %s', newItemKey));

Related

Unsorted keys in note will be sorted

I'm creating a stave note with multiple keys:
const staveNote: vexflow.Flow.StaveNote = new this.VF.StaveNote({
keys: this.renderNotesSortedByPitch(placedChord.notes),
duration: chordDuration,
auto_stem: true,
clef: Clef.TREBLE
});
private renderNotesSortedByPitch(notes: Array<Note>): Array<string> {
const vexflowNotes: Array<string> = new Array<string>();
notes
// this.sortNotesByPitch(notes)
.forEach((note: Note) => {
vexflowNotes.push(this.renderNote(note));
});
return vexflowNotes;
}
private sortNotesByPitch(notes: Array<Note>): Array<Note> {
return notes.sort((noteA: Note, noteB: Note) => {
return noteA.pitch.chroma.value - noteB.pitch.chroma.value <--- No arithmetic operation on strings
});
}
and I get the following warning in the browser console:
Warning: Unsorted keys in note will be sorted. See https://github.com/0xfe/vexflow/issues/104 for details. Error
at Function.b.StackTrace (http://localhost:4200/vendor.js:93990:4976)
at Function.b.W (http://localhost:4200/vendor.js:93990:5134)
at http://localhost:4200/vendor.js:93990:255605
at Array.forEach (<anonymous>)
at e.value (http://localhost:4200/vendor.js:93990:255572)
at new e (http://localhost:4200/vendor.js:93990:250357)
at SheetService.vexflowRenderSoundtrack (http://localhost:4200/main.js:2083:51)
at SheetService.createSoundtrackSheet (http://localhost:4200/main.js:2004:14)
at SheetComponent.createSheet (http://localhost:4200/main.js:2465:35)
at SheetComponent.ngAfterViewInit (http://localhost:4200/main.js:2452:14)
I understand I need to provide the keys already sorted the way Vexflow is sorting them.
A similar issue is also described there.
How to sort the keys with the note.pitch.chroma.value being a string ?
It'd be nice to have some method in the same fashion as:
staveNote.setKeyStyle(0, { fillStyle: 'red' });
Say, some such method:
staveNote.setDotted(0);
Or:
staveNote.setKeyStyle(0, { fillStyle: 'red', dotted: true });
UPDATE: Following a suggestion I could create the methods to sort the notes before adding them as keys in the stave:
private getNoteFrequency(note: Note): number {
return Tone.Frequency(note.renderAbc()).toFrequency();
}
private sortNotesByPitch(notes: Array<Note>): Array<Note> {
return notes.sort((noteA: Note, noteB: Note) => {
return this.getNoteFrequency(noteA) - this.getNoteFrequency(noteB);
});
}
The Vexflow warning message was no longer displayed in the browser console.
Vexflow expects your notes to be sorted vertically, no way around that.
You need to write your own function to compare two notes given as strings.
here's a working note-string-comparison-function which doesn't take accidentals into account: repl.it/repls/WobblyFavorableYottabyte
edited for clarity, thanks #gristow for the correction!

cy.url() and/or cy.location('href') does not return a string

I have an editor page. When I add any content and click the "Save" button my URL will change, adding a random id in the URL. I want to check if my ID's are changing every time when I click the "Save button".
I save the URL result in variable and want to check it, I do it like this:
const currentURL = cy.url();
cy.get('.editor-toolbar-actions-save').click();
cy.url().should('not.eq', currentURL);
But my currentURL variable's type is not string:
expected http://localhost:8080/editor/37b44d4d-48b7-4d19-b3de-56b38fc9f951 to not equal { Object (chainerId, firstCall) }
How I can use my variable?
tl;dr
Cypress commands are asynchronous, you have to use then to work with their yields.
cy.url().then(url => {
cy.get('.editor-toolbar-actions-save').click();
cy.url().should('not.eq', url);
});
Explanation
A similar question was asked on GitHub, and the official document on aliases explains this phenomenon in great detail:
You cannot assign or work with the return values of any Cypress command. Commands are enqueued and run asynchronously.
The solution is shown too:
To access what each Cypress command yields you use .then().
cy.get('button').then(($btn) => {
// $btn is the object that the previous
// command yielded us
})
It is also a good idea to check out the core concepts docs's section on asynchronicity.
These commands return a chainable type, not primitive values like strings, so assigning them to variables will require further action to 'extract' the string.
In order to get the url string, you need to do
cy.url().then(urlString => //do whatever)
I have been having the same issue and so far most consistent method has been to save the URL to file and read it from file when you need to access it again:
//store the url into a file so that we can read it again elsewhere
cy.url().then(url => {
const saveLocation = `cypress/results/data/${Cypress.spec.name}.location.txt`
cy.writeFile(saveLocation, getUrl)
})
//elsewhere read the file and do thing with it
cy.readFile(`cypress/results/data/${Cypress.spec.name}.location.txt`).then((url) => {
cy.log(`returning back to editor ${url}`)
cy.visit(url)
})
Try this:
describe("Test Suite", () => {
let savedUrl;
beforeEach(() => {
cy.visit("https://duckduckgo.com/");
cy.url().then(($url) => {
savedUrl = $url;
});
});
it("Assert that theURL after the search doens't equal the URL before.", () => {
cy.get("#search_form_input_homepage").type("duck");
cy.get("#search_button_homepage").click();
// Check if this URL "https://duckduckgo.com/?q=duck&t=h_&ia=web"
// doesn't equal the saved URL "https://duckduckgo.com/"
cy.url().should("not.eq", savedUrl);
});
});
Refer below code snippet, Here you can get the current URL and store it in a variable, do print via cy.log()
context('Get Current URL', () => {
it('Get current url and print', () => {
cy.visit('https://docs.cypress.io/api/commands/url')
cy.url().then(url => {
const getUrl = url
cy.log('Current URL is : '+getUrl)
})
})
})
#Max thanks this helped to get some ideas on different versions.
The way I did it is:
Create a .json file in your fixtures folder (name it whatever you want).
On the new .json file, only add: { } brackets and leave the rest blank. The function will self populate that .json file.
Create a new function on the commands page to easily call it on your test.
It would probably be best to create two functions, 1 function to write url or the sliced piece of the url, and the another function to call it so you can use it.
A. Example of 1st method, this method cuts the id off of the URL and stores it on the .json file:
Cypress.Commands.add('writeToJSON', (nameOfJSONSlicedSection) =>
{
cy.url().then(urlID =>
{
let urlBit = urlID.slice(urlID.indexOf('s/') + 2, urlID.indexOf('/edit'))
cy.writeFile('cypress/fixtures/XYZ.json', {name: nameOfJSONSlicedSection, id: urlBit}) /*{ }<-- these will populate the json file with name: xxxxx and id:xxxxx, you can changes those to whatever meets your requirements. using .slice() to take a section of the url. I needed the id that is on the url, so I cut only that section out and put it on the json file.*/
})
})
B. 2nd example function of calling it to be used.
This function is to type in the id that is on the url into a search box, to find the item I require on a different it() block.
Cypress.Commands.add('readJSONFile', (storedJSONFile) =>
{
cy.readFile('cypress/fixtures/XYZ.json').its('id').then((urlSetter) => {
cy.log(storedJSONFile, 'returning ID: ' + urlSetter)
//Search for Story
cy.get('Search text box').should('be.visible').type(urlSetter, {delay: 75})
})
})
/*here I use a .then() and hold the "id" with "urlSetter", then I type it in the search box to find it by the id that is in the URL. Also note that using ".its()" you can call any part section you require, example: .its('name') or .its('id') */
I hope this helps!

How to pass Dictionary Objects In HttpUrl In ANgular7?

First of all i wanna say sorry for that if my question is silly question,Iam confused with this because im new in Angular.
Before asking question i want to introduce about my code,
this is the get functon that exactly i have called api,
get(feepaid_report: FeepaidReport): Observable<FeepaidReport[]> {
const options = this._utils.makeOptions(this._headers);
return this._http.get(`${this._feepaidreportUrl}`, options).pipe(
map((res: Response) => res.json()),
tap(
data => this.afterGetRequest(),
error => { console.log(error); }
));
}
Here in this code _feepaidreportUrl is my baseUrl that looks like this:
private _feepaidreportUrl = `${new Config().api}/report/feepaid_report/`;
And the my argument feepaid_report of type FeepaidReport is comes with data of dictionary like this,
FeepaidReport: {paid_date: "2019-01-03", classes: "class12"}
And i want to append this dictionary (i.e feepaidreport data) in url so that i can pass the url for backend like that:
baseurl/?paid_date=2019-01-03&classes=class12
Hope you will understand my question
Above problem is solved by doing this:
get(feepaid_report: FeepaidReport): Observable<FeepaidReport[]> {
var url = `${this._feepaidreportUrl}/?`
for(var key in feepaid_report){
var val = feepaid_report[key];
if (typeof(val) !=='undefined'){
url = url + key + '=' + val + '&'
}
}
const options = this._utils.makeOptions(this._headers);
return this._http.get(url, options).pipe(
map((res: Response) => res.json()),
tap(
data => this.afterGetRequest(),
error => { console.log(error); }
));
}

Unable to figure out how to use post method, for a suitescript written in Netsuite

I am trying to do use the post method for a simple suitescript program, i am very new to this.
In Netsuite i have written a suitescript as follows.
function restPost()
{
var i = nlapiLoadRecord('department', 115);
var memo = nlapisetfieldvalue('custrecord225', ' ');// this is a customfield, which i want to populate the memo field, using rest client in firefox
var recordId = nlapiSubmitRecord(i);
}
i have created a script record and uploaded this suitescript and even copied the external URL to paste it in restclient.
In Restclient(firefox plugin), pasted the external URL, i have given the method as post, header authorization given, content-type: application/json, and in body i put in {"memo":"mynamehere"};
In this the error i get is
message": "missing ) after argument list
I even tried it by writting other suitescript programs the errors i get is as follows:
Unexpected token in object literal (null$lib#3) Empty JSON string
Invalid data format. You should return TEXT.
I am kinda new to the programming world, so any help would be really good.
I think you are trying to create a RESTlet for POST method. Following is the sample code for POST method -
function createRecord(datain)
{
var err = new Object();
// Validate if mandatory record type is set in the request
if (!datain.recordtype)
{
err.status = "failed";
err.message= "missing recordtype";
return err;
}
var record = nlapiCreateRecord(datain.recordtype);
for (var fieldname in datain)
{
if (datain.hasOwnProperty(fieldname))
{
if (fieldname != 'recordtype' && fieldname != 'id')
{
var value = datain[fieldname];
if (value && typeof value != 'object') // ignore other type of parameters
{
record.setFieldValue(fieldname, value);
}
}
}
}
var recordId = nlapiSubmitRecord(record);
nlapiLogExecution('DEBUG','id='+recordId);
var nlobj = nlapiLoadRecord(datain.recordtype,recordId);
return nlobj;
}
So after deploying this RESTlet you can call this POST method by passing following sample JSON payload -
{"recordtype":"customer","entityid":"John Doe","companyname":"ABCTools Inc","subsidiary":"1","email":"jdoe#email.com"}
For Authorization you have to pass request headers as follows -
var headers = {
"Authorization": "NLAuth nlauth_account=" + cred.account + ", nlauth_email=" + cred.email +
", nlauth_signature= " + cred.password + ", nlauth_role=" + cred.role,
"Content-Type": "application/json"};
I can understand your requirement and the answer posted by Parsun & NetSuite-Expert is good. You can follow that code. That is a generic code that can accept any master record without child records. For Example Customer Without Contact or Addressbook.
I would like to suggest a small change in the code and i have given it in my solution.
Changes Below
var isExistRec = isExistingRecord(objDataIn);
var record = (isExistRec) ? nlapiLoadRecord(objDataIn.recordtype, objDataIn.internalid, {
recordmode: 'dynamic'
}) : nlapiCreateRecord(objDataIn.recordtype);
//Check for Record is Existing in Netsuite or Not using a custom function
function isExistingRecord(objDataIn) {
if (objDataIn.internalid != null && objDataIn.internalid != '' && objDataIn.internalid.trim().length > 0)
return true;
else
return false;
}
So whenever you pass JSON data to the REStlet, keep in mind you have
to pass the internalid, recordtype as mandatory values.
Thanks
Frederick
I believe you will want to return something from your function. An empty object should do fine, or something like {success : true}.
Welcome to Netsuite Suitescripting #Vin :)
I strongly recommend to go through SuiteScript API Overview & SuiteScript API - Alphabetized Index in NS help Center, which is the only and most obvious place to learn the basics of Suitescripting.
nlapiLoadRecord(type, id, initializeValues)
Loads an existing record from the system and returns an nlobjRecord object containing all the field data for that record. You can then extract the desired information from the loaded record using the methods available on the returned record object. This API is a core API. It is available in both client and server contexts.
function restPost(dataIn) {
var record = nlapiLoadRecord('department', 115); // returns nlobjRecord
record.setFieldValue('custrecord225', dataIn.memo); // set the value in custom field
var recordId = nlapiSubmitRecord(record);
return recordId;
}

Why i don't see my #replies in conversation view in twitter?

I need to reply to one particular twitter status. I'm using following functions. And I've used Abraham's twitteroauth library in php.
public function replyToTwitterStatus($user_id,$status_id,$twitt_reply,$account_name)
{
$connection= $this->getTwitterConnection($user_id,$account_name);
try{
$responce = $this->postApiData('statuses/update', array('status' => $twitt_reply,'in_reply_to_status_id '=> $status_id),$connection);
}
catch(Exception $e){
echo $message = $e->getMessage();
exit;
}
}
// this function will handle all post requests
// To post/update twitter data
// To post/update twitter data
public function postApiData($request,$params = array(),$connection)
{
if($params == null)
{
$data = $connection->post($request);
}
else
{
$data = $connection->post($request,$params);
}
// Need to check the error code for post method
if($data->errors['0']->code == '88' || $data->errors['0']->message == 'Rate limit exceeded')
{
throw new Exception( 'Sorry for the inconvenience,Please wait for minimum 15 mins. You exceeded the rate limit');
}
else
{
return $data;
}
}
But the issue is that it is not maintaining the conversation view and it is update like normal status for e.g #abraham hello how are you. but that "View conversation" is not coming. Like expanding menu is not coming.
Please do needful
Thanks
You've got an unwanted space in your in_reply_to_status_id key which causes that parameter to be ignored.
This call:
$responce = $this->postApiData('statuses/update', array(
'status' => $twitt_reply,
'in_reply_to_status_id ' => $status_id
), $connection);
should look like this:
$responce = $this->postApiData('statuses/update', array(
'status' => $twitt_reply,
'in_reply_to_status_id' => $status_id
), $connection);
Also, make sure that the $status_id variable is being handled as a string. Although they look like numbers, most ids will be too big to be represented as integers in php, so they'll end up being converted to floating point which isn't going to work.
Lastly, make sure you have include the username of the person you are replying to in the status text. Quoting from the documentation for the in_reply_to_status_id parameter:
Note:: This parameter will be ignored unless the author of the tweet this parameter references is mentioned within the status text. Therefore, you must include #username, where username is the author of the referenced tweet, within the update.

Resources