0

I have a switchmap that won't go inside. I had it working earlier today, but for some reason now it's not outputting alert("INSIDE SWITCHMAP") or the console.logs inside the switchmap.

Also this little block of alerts

    alert(userId);
    alert(currentPage);
    alert(auctionId);

outputs the correct values so none of them are null.

Any suggestions? I appreciate the help!

import { Injectable, OnDestroy } from "@angular/core";
import { HttpClient, HttpParams } from "@angular/common/http";
import { Router } from "@angular/router";
import { Subject } from "rxjs";
import { Bidding } from "./bidding.model";
import { Watching } from "../watching/watching.model";
import { PasswordReset } from "../reset-password/password.model";
import { environment } from 'src/environments/environment';
import { takeUntil, switchMap } from 'rxjs/operators';

@Injectable({ providedIn: "root" })
export class BiddingService implements OnDestroy {
  destroy = new Subject();
  constructor(private http: HttpClient, private router: Router) { }

  submitBid(
    auctionId: string,
    currentBid: string,
    userId: string,
    biddingGroup: string[],
    auctionEndDateTime: string,
    lastBidderName: string,
    runnerUpBidderName: string,
    runnerUpBid: string,
    reservePriceBeat: boolean,
    currentPage: string
  ) {

    let bidderName;
    let listingHasBeenFound = false;

    const bidding: Bidding = {
      id: auctionId,
      bidderId: userId,
      lastBidTimeStamp: null,
      currentBid: currentBid,
      runnerUpBidderName: runnerUpBidderName,
      runnerUpBid: runnerUpBid,
      lastBidderName: lastBidderName,
      biddingGroup: biddingGroup,
      auctionEndDateTime: auctionEndDateTime,
      reservePriceBeat: reservePriceBeat
    };

    alert("OUTSIDE SWITCHMAP")
    alert(userId);
    alert(currentPage);
    alert(auctionId);

    return this.getUserNameandListingPage(userId, currentPage, auctionId).pipe(
      switchMap(res => {
        alert("INSIDE SWITCHMAP")
        bidderName = res.posts.username;
        listingHasBeenFound = res.listingHasBeenFound;
        console.log("bidderName");
        console.log(bidderName);
        console.log(listingHasBeenFound);

        console.log(res);

        return this.http.patch(
          environment.api_url + `/listings/${bidding.id}`,
          bidding
        );
      })
    );

  }



  getUserNameandListingPage(id: string, currentPage: string, listingId: string) {


    const params = new HttpParams()
      .set("userIdBidder", id)
      .set("listingId", listingId)
      .set("currentPage", currentPage);

    return this.http.get<{ posts: any; listingHasBeenFound: boolean }>(
      environment.api_url + `/user/${id}`, { params }
    );
  }



  ngOnDestroy() {
    this.destroy.next();
    this.destroy.complete();
  }

}

confirmBid component

import {
  Component,
  Output,
  EventEmitter,
  Inject,
  OnInit,
  OnDestroy
} from "@angular/core";
import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material";
import { AuctionListingsComponent } from "../auction-listings/auction-listings.component";
import { BiddingService } from "../auction-listings/bidding.service";
import { ToastrService } from "ngx-toastr";
import * as Ably from "ably";
import { SubmitListingService } from "../submit-listing/submit-auction.service";
import { Subject } from "rxjs";
import { startWith, filter, takeUntil } from "rxjs/operators";
let api = process.env.ablyAPi;
let options: Ably.Types.ClientOptions = { key: api };
let client = new Ably.Realtime(options); /* inferred type Ably.Realtime */
let channel = client.channels.get(
  "auctions"
); /* inferred type Ably.Types.RealtimeChannel */

@Component({
  selector: "app-confirmation-dialog",
  templateUrl: "./confirmation-dialog.component.html",
  styleUrls: ["./confirmation-dialog.component.css"]
})
export class ConfirmationDialogComponent implements OnInit, OnDestroy {
  currentBid: string;
  bidInput: string;
  auctionId: string;
  userId: string;
  runnerUpBidderName: string;
  runnerUpBid: string;
  bidderName: string;
  biddingGroup: string[];
  currentData: any[];
  auctionEndDateTime: string;
  currentPage: string;
  success: boolean;
  listingHasBeenFound: boolean;
  username: string;
  reservePriceBeat = false;
  destroy = new Subject();

  constructor(
    public dialogRef: MatDialogRef<AuctionListingsComponent>,
    @Inject(MAT_DIALOG_DATA) public data: ConfirmationDialogComponent,
    private biddingService: BiddingService,
    private toastr: ToastrService,
    private submitListingService: SubmitListingService
  ) { }

  ngOnInit() {
    this.auctionId = this.data.auctionId;
    this.runnerUpBid = this.data.currentBid;
    this.bidInput = this.data.bidInput;
    this.userId = this.data.userId;
    this.runnerUpBidderName = this.data.runnerUpBidderName;
    this.biddingGroup = this.data.biddingGroup;
    this.currentPage = this.data.currentPage;
    this.reservePriceBeat = this.data.reservePriceBeat;
    this.auctionEndDateTime = this.data.auctionEndDateTime;
    this.listingHasBeenFound = this.data.listingHasBeenFound;
    this.bidderName = this.data.bidderName;

  }

  ngOnDestroy() {
    this.destroy.next();
    this.destroy.complete();
  }

  confirmBid() {
    const data = {
      auctionId: this.auctionId,
      lastBid: this.bidInput,
      lastBidderId: this.userId,
      username: this.username
    };
    // Optionally, you can use a callback to be notified of success or failure
    channel.publish("auctions", data);
    this.biddingService
      .submitBid(
        this.auctionId,
        this.bidInput,
        this.userId,
        this.biddingGroup,
        this.auctionEndDateTime,
        this.username,
        this.runnerUpBidderName,
        this.runnerUpBid,
        this.reservePriceBeat,
        this.currentPage
      )
      .pipe(takeUntil(this.destroy))
      .subscribe(res => {
        console.log("RES");
        console.log(res);
      });

    this.toastr.success("Your bid has been submitted", "", {
      timeOut: 2000
    });

    this.success = true;

    var returnData = [
      {
        newEndTime: this.auctionEndDateTime,
        auctionId: this.auctionId,
        success: this.success,
        username: this.username
      }
    ];

    this.dialogRef.close(returnData);
  }

  cancel() {

    this.dialogRef.close(true);
    this.success = false;
  }
}

api call

if (req.query.userIdBidder) {
    console.log("correct path!");
    console.log(req.query.userIdBidder);

    Post.find({
      $and: [
        { auctionType: { $eq: "publicAuction" } },
        { auctionEndDateTime: { $gte: Date.now() } },
        { blacklistGroup: { $ne: req.query.bidderUserId } },
        // { startTime: { $lte: Date.now() } }
      ]
    }) //test
      .skip(10 * (req.query.currentPage - 1))
      .sort({ dateCreated: -1 })
      .limit(10)
      .then(listings => {

        console.log("listings");

        let listingHasBeenFound = false;
        for (let i = 0; i < listings.length; i++) {

          console.log("i");
          console.log(i);
          console.log(req.query.listingId);
          console.log(listings[i]._id);
          if (listings[i]._id.toString().trim() === req.query.listingId.toString().trim()) {
            listingHasBeenFound = true;
            break;
          }

        }

        console.log("CURRENT PAGE " + req.query.listingId);


        User.findById({ _id: req.query.userIdBidder })
          .select("username")
          .then(documents => {
            console.log("HERE WE ARE")
            res.status(200).json({
              message: "User account located!",
              posts: documents,
              listingHasBeenFound: listingHasBeenFound
            });
          });
      }).catch((res) => {

        console.log("ERROR");
        console.log(res);
      });

  }
user6680
  • 79
  • 6
  • 34
  • 78
  • Where is the code that is calling `submitBid`? – julianobrasil Mar 20 '20 at 17:30
  • I updated my question with the submitBid component. It's a mat-dialog that handles that call. But I don't think that's the issue. So it appears that it is calling the ```return this.getUserNameandListingPage(userId, currentPage, auctionId).pipe(``` because my nodejs output shows it hitting that API ((I can see backend console.logs), but it's not returning the response. I added the ```getUserNameandListingPage``` backend too – user6680 Mar 20 '20 at 17:46
  • If you have an error in `getUserNameandListingPage`, your `switchMap` wouldn't be called. You can try to use a `catchError` on that method to see what you catch. – julianobrasil Mar 20 '20 at 17:51
  • I'm saying that the http call inside `getUserNameandListingPage` can be throwing an error. – julianobrasil Mar 20 '20 at 17:52
  • Do you mean catch on the backend? Because I have this ```.catch((res) => { console.log("ERROR"); console.log(res); });``` but it never hits that catch It's possible I'm doing the catch wrong though. the .then(documents => does return the information I need though so I don't think it's throwing an error – user6680 Mar 20 '20 at 17:53
  • No, at the frontend. Inside `getUserNameandListingPage`, try this: `this.http.get<{ posts: any; listingHasBeenFound: boolean }>( environment.api_url + `/user/${id}`, { params } ).pipe(catchError(e => of({posts:{username: 'ABSURD NAME'},listingHasBeenFound: false}))` – julianobrasil Mar 20 '20 at 17:57
  • Ok gotcha. I've never used a pipe like that before. I updated my code to this: https://pastebin.com/Y1g3dFBP ,but I don't get any output of any kind in the console. Sorry I'm just familiar with a catchError pipe. I see there's no console.log in that catchError statement so how would I know if the error was caught? – user6680 Mar 20 '20 at 18:06
  • I'm just making sure that your HTTP call is returning an observable, even if there's an error. That `alert("INSIDE SWITCHMAP")` should be executed. As you're not seeing anything, that's not the problem. – julianobrasil Mar 20 '20 at 18:14
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/210025/discussion-between-user6680-and-julianobrasil). – user6680 Mar 20 '20 at 18:17

1 Answers1

1

Modify a little bit your confirmBid() method in your ConfirmationDialogComponent (move all the code after the closing subscribe parenthesis to inside the subscriber function):

confirmBid() {
    const data = {
      auctionId: this.auctionId,
      lastBid: this.bidInput,
      lastBidderId: this.userId,
      username: this.username
    };
    // Optionally, you can use a callback to be notified of success or failure
    channel.publish("auctions", data);
    this.biddingService
      .submitBid(
        this.auctionId,
        this.bidInput,
        this.userId,
        this.biddingGroup,
        this.auctionEndDateTime,
        this.username,
        this.runnerUpBidderName,
        this.runnerUpBid,
        this.reservePriceBeat,
        this.currentPage
      )
      .pipe(takeUntil(this.destroy))
      .subscribe(res => {
          this.toastr.success("Your bid has been submitted", "", {
            timeOut: 2000
          });

          this.success = true;

          const returnData = [{
              newEndTime: this.auctionEndDateTime,
              auctionId: this.auctionId,
              success: this.success,
              username: this.username
          }];

          this.dialogRef.close(returnData);
      });
  }
julianobrasil
  • 8,954
  • 2
  • 33
  • 55