I want to subscribe in company-list.component on getCompanies() from the company.service. However I get the following error:
Cannot read property 'subscribe' of undefined
This is the code:
company.service.ts
getCompaniesOfUser() {
let r;
this.userService.getUser().subscribe(
res=> r = res,
err => console.log(err),
()=>(this.getCompaniesWithSpecificLink())
)
}
getCompaniesWithSpecificLink() {
if (isAdmin == false) {
url = '/user/companies';
} else {
url = '/companies';
}
return this.getCompanies(url);
}
getCompanies(url):Observable<Company[]> {
return this.http.get(this.host + url)
.map((res:Response) => res.json());
}
company-list.component.ts
companies:Company[];
public getTheCompanies() {
this._companyService.getCompaniesOfUser()
.subscribe(companies => this.companies = companies); <-- the error occurred here
}
Subscribe method must be used on an observable but your getCompaniesOfUser() method is not returning anything thus is a void method.
If you want to call back-to-back rest services. Like one's input depending on the others' output. You should use the flatMap operator.
Check this answer for example: https://stackoverflow.com/a/36712707/5706293
Something like this should work:
getCompaniesOfUser() {
return this.userService.getUser().flatMap( (resp) => {
return this.getCompaniesWithSpecificLink();
});
}
Related
artistSelected(item: any) {
console.log(item.artist);
this.songsServices.getSongsListArtist(item.artist).subscribe(
result => {
this.songsServices.artistList = result;
this.route.navigate(['./artistsongs']);
},
error => {
console.log('There is an error');
}
);
}
Service
getSongsListArtist(album: string) {
const completeUrl = `${environment.API_URL}?album=${album}`;
return this.httpClient.get(encodeURI(completeUrl));
}
artistList(artistsongs: string) {
return artistsongs;
}
I am facing an error in this. Please sole me how to pass the object from one ts file to another ts file by using service.
artistList(artistsongs: string) {
return artistsongs;
}
change to:
artistList(artistsongs: any) {
return artistsongs;
}
As i understand when you call getSongsListArtist it will return an array object or an object not a string only. You can use typeof() to check this.httpClient.get(encodeURI(completeUrl)) return what kind of type.
When I am trying to check presence of not presented element/ button. I am getting:
Jasmine timeout exception
My code like
getName(): any {
let name = element(by.id("xxxxxx"));
return name.isPresent().then((ispresent) => {
if (ispresent) {
return name.getText();
} else {
return '';
}
})
}
I am trying to access that method expect(method).toequal('');
It should run, because if not present i am expecting empty string but i am getting Jasmine timeout.. I didn't added any waits any where.
isPresent()
From the GitHub repo, ElementFinder.isPresent
isPresent(): wdpromise.Promise<boolean> {
return this.count().then((count) => {
return count > 0;
});
}
isPresent checks for a count, but does not catch if there is an error. If the count throws, we should probably return 0. Getting a text for an element that does not exist should also have throw a promise rejection.
Note: It might be better to change your method to async / await (optional).
async getName(): webdriver.promise.Promise<string> {
const name = element(by.id("xxxxxx"));
try {
return name.getText();
} catch (e) {
return '';
}
}
Or not async / await
getName(): webdriver.promise.Promise<string> {
const name = element(by.id("xxxxxx"));
return name.getText().catch(e) {
return '';
}
}
Try the below one
async getName() {
let name = element(by.id("xxxxxx"));
let value: string = '';
await name.ispresent().then((ispresent) => {
if (ispresent) {
value=name.getText();
}
});
return value;
}
Hope it helps you
I have a problem getting the result from a Cloud Function.
This is my Cloud Function:
exports.retrieveTrips = functions.https.onCall((data, context) => {
const uidNumber = context.auth.uid;
var arrayOfResults = new Array();
var idOfFoundDoc;
var query = admin.firestore().collection('Users').where('UID','==', uidNumber);
query.get().then(snapshot =>
{
snapshot.forEach(documentSnapshot =>
{
idOfFoundDoc = documentSnapshot.id;
});
var queryDoc = admin.firestore().collection('Users').doc(idOfFoundDoc).collection('Trips');
queryDoc.get().then(snapshot =>
{
snapshot.forEach(documentSnapshot =>
{
arrayOfResults.push(documentSnapshot.data());
});
console.log('ARRAY: ' , arrayOfResults);
return arrayOfResults;
})
.catch (err =>
{
console.log ('Error adding document: ', err);
});
})
.catch (err => {
//response.send('Error getting documents', err);
console.log ('Error getting documents', err);
});
And this is the code that I have in my application.
#IBAction func RetrieveTripsButton(_ sender: Any)
{
self.functions.httpsCallable("retrieveTrips").call() {(result, error) in
if let error = error as NSError? {
if error.domain == FunctionsErrorDomain
{
let message = error.localizedDescription
print ("Message: " + message)
}
return
}
print ("Result: -> \(type(of: result))")
print("Result.data type: \(type(of: result?.data))");
print ("Result.data -> \(result?.data)")
}
}
And this is the printed result.
Result: -> Optional<FIRHTTPSCallableResult>
Result.data type: Optional<Any>
Result.data -> Optional(<null>)
The console log is able to print arrayOfResults correctly. Furthermore, when I change this functions to onRequest and feed it the relevant information, the res.status(200).send(arrayOfResults) is able to display the array of JSON in the page.
If I placed the return arrayOfResults; outside of the .then function, I would get a result along with an empty array. My issue is similar to this problem here but I'm unable to receive even that when I return { text: "some_data" }; .
Any help would be great, thank you!
You have to chain the different promises and return the result of the promises chain, as follows.
Note that it is actually what the OP explains in his answer to the SO post you mention "The issue was that I forgot to return the actual promise from the cloud function".
exports.retrieveTrips = functions.https.onCall((data, context) => {
const uidNumber = context.auth.uid;
const arrayOfResults = new Array();
let idOfFoundDoc;
const query = admin.firestore().collection('Users').where('UID','==', uidNumber);
return query.get().then(snapshot => { // here add return
snapshot.forEach(documentSnapshot =>
{
idOfFoundDoc = documentSnapshot.id;
});
const queryDoc = admin.firestore().collection('Users').doc(idOfFoundDoc).collection('Trips');
return queryDoc.get(); // here add return and chain with then()
})
.then(snapshot => {
snapshot.forEach(documentSnapshot => {
arrayOfResults.push(documentSnapshot.data());
});
console.log('ARRAY: ' , arrayOfResults);
return { arrayOfResults : arrayOfResults }; //return an object
})
.catch (err => {
console.log ('Error getting documents', err);
//Here you may return an error as per the documentation https://firebase.google.com/docs/functions/callable#handle_errors, i.e. by throwing an instance of functions.https.HttpsError
});
});
I would also suggest that you look at these two videos from the Firebase team, about Cloud Functions and promises: https://www.youtube.com/watch?v=7IkUgCLr5oA and https://www.youtube.com/watch?v=652XeeKNHSk.
as title says, when i wanna update TextDocumentContentProvider with different query params by calling update method provideTextDocumentContent is not called...
only way i managed to get it working was with same URI as in calling
vscode.commands.executeCommand('vscode.previewHtml', URI, 2, 'Storybook');
relevant part of code:
// calculates uri based on editor state - depends on actual caret position
// all uris will start with 'storybook://preview'
function getPreviewUri(editor: vscode.TextEditor): vscode.Uri;
// transforms uri, so web server will understand
// ex: 'storybook://preview?name=fred' -> 'http://localhost:12345/preview/fred?full=1'
function transformUri(uri: vscode.Uri): vscode.Uri;
class StorybookContentProvider implements vscode.TextDocumentContentProvider
{
provideTextDocumentContent(uri: vscode.Uri): string {
var httpUri = transformUri(uri);
return `<iframe src="${httpUri}" />`;
}
onDidChange = new vscode.EventEmitter<vscode.Uri>();
update(uri: vscode.Uri) {
this.onDidChange(uri);
}
}
export function activate(context: vscode.ExtensionContext)
{
vscode.workspace.onDidChangeTextDocument(
(e: vscode.TextDocumentChangeEvent) => {
if (e.document === vscode.window.activeTextEditor.document) {
const previewUri = getPreviewUri(vscode.window.activeTextEditor);
provider.update(previewUri);
}
}
);
vscode.window.onDidChangeTextEditorSelection(
(e: vscode.TextEditorSelectionChangeEvent) => {
if (e.textEditor === vscode.window.activeTextEditor) {
const previewUri = getPreviewUri(vscode.window.activeTextEditor);
provider.update(previewUri);
}
}
);
const provider = new StorybookContentProvider();
context.subscriptions.push(
vscode.commands.registerCommand('extension.showStorybook', () => {
vscode.commands.executeCommand('vscode.previewHtml', vscode.Uri.parse('storybook://preview'), 2, 'Storybook')
}),
vscode.workspace.registerTextDocumentContentProvider('storybook', provider)
);
}
There is a parse CloudCode function created as such:
Parse.Cloud.define("getCurrentEvents", function(request, response) {
var TimedEvent = Parse.Object.extend("TimedEvent");
var query = new Parse.Query(TimedEvent);
query.greaterThan("expiresOn", new Date());
query.find({
success: function(results) {
response.success(results);
},
error: function(error) {
response.error("There was an error while looking for TimedEvents");
}
});
});
It returns an array of TimedEvent, as shown in the curl test here:
{"result":[{"expiresOn":{"__type":"Date","iso":"2014-07-31T22:31:00.000Z"},"playMode":"Normal","tableId":"Carnival","objectId":"J1LSO3EnKi","createdAt":"2014-07-28T21:48:22.983Z","updatedAt":"2014-07-28T22:32:14.304Z","__type":"Object","className":"TimedEvent"}]}
When trying to access it from Unity SDK however, I get a "cannot convert to destination type" exception with the following line:
System.Threading.Tasks.Task<Parse.ParseObject[]> task =
Parse.ParseCloud.CallFunctionAsync<Parse.ParseObject[]> ("getCurrentEvents", parameters);
I also tried
System.Threading.Tasks.Task<IEnumerable<Parse.ParseObject>> task =
Parse.ParseCloud.CallFunctionAsync<IEnumerable<Parse.ParseObject[]>> ("getCurrentEvents", parameters);
with the same (lack of) results. What kind of signature is the SDK expecting?
Have you tried something like this (without IEnumerable?):
Threading.Tasks.Task<Parse.ParseObject> task = Parse.ParseCloud.CallFunctionAsync<Parse.ParseObject>("getCurrentEvents", parameters);
But better yet, you could extend ParseObject to create your own TimedEvent class in Unity, like this:
[ParseClassName("TimeEvent")]
public class TimeEvent : ParseObject
{
[ParseFieldName("expiresOn")]
public DateTime expiresOn
{
get { return GetProperty<DateTime>("expiresOn"); }
set { SetProperty(value, "expiresOn"); }
}
[ParseFieldName("playMode")]
public string playMode
{
get { return GetProperty<string>("playMode"); }
set { SetProperty(value, "playMode"); }
}
[ParseFieldName("tableId")]
public string tableId
{
get { return GetProperty<string>("tableId"); }
set { SetProperty(value, "tableId"); }
}
// any other fields you want to access
}
Then you can query your data like this:
IEnumerator getTimedEvents(Dictionary<string, object> parameters)
{
var cloudTask = Parse.ParseCloud.CallFunctionAsync<TimeEvent>("getCurrentEvents", parameters);
while (!cloudTask.IsCompleted)
yield return null;
if (cloudTask.IsCanceled || cloudTask.IsFaulted)
{
// handle error
}
else
{
TimeEvent t = cloudTask.Result;
// do stuff with t
}
}
P.S. Don't forget to register your Parse class somewhere (I usually do it in the Awake() of an early GameObject). In your case, you would do it like this:
Parse.ParseObject.RegisterSubclass<TimedEvent>();