1
votes

I have a stream of Observable threads:

threads: Observable<{ [key: string]: Thread }>;

I want to create a function that iterates every object in my collection to find out if the id given in threadId parameter already exists. If it already exists, the function must return false.

My function does not work, but I do not know why. She always turns me false :

knowNewThread(threadId: string): boolean {
let newThread: boolean = false;
this.threads
  .map((threadDictionary: { [key: string]: Thread }) => {
    for (let key in threadDictionary) {
      if (threadDictionary[key].id === threadId) {
        newThread = true;
      }
    }
  });
return newThread;
}

EDIT :

I do not know how to do it. I am inspired by my function which allows me to return the thread according to the threadId given parameter:

getThreadFromSubscription(threadId: string): Observable<Thread> {
return this.threads
  .filter((threadDictionary: { [key: string]: Thread }) => {
    return Object.keys(threadDictionary).some((key) =>
      threadDictionary[key].id === threadId);
  })
  .map((threadDictionary: { [key: string]: Thread }) => {
    for (let key in threadDictionary) {
      if (threadDictionary[key].id === threadId)
      {
        return threadDictionary[key];
      }
    }
  }).first();
}

And after to subscribe I do this :

this.getThreadFromSubscription(objMessage.id)
    .subscribe ((thread: Thread) => {
      objMessage.thread = thread;
});

Should I be inspired to create my function or is it different?

Initializing my thread variable in threadService :

this.threads = messageService.messages
  .map((messages: Message[]) => {
    const threads: { [key: string]: Thread } = {};
    messages.map((message: Message) => {
      threads[message.thread.id] = threads[message.thread.id] ||
        message.thread;

      const messagesThread: Thread = threads[message.thread.id];
      if (!messagesThread.lastMessage ||
        messagesThread.lastMessage.date < message.date) {
        messagesThread.lastMessage = message;
      }
    });
    return threads;
  });

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

EDIT

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

When I subscribe to my knowNewThread function, it returns a list of boolean variables. Outside I would like that when I scoucirs to this function, it returns a single boolean variable true or false.

Here is what I wrote:

knowNewThread(threadId: string): Observable<boolean> {
return this.threads
  .map((threadDictionary: { [key: string]: Thread }) => {
    let newThread: boolean = false;
    for (let key in threadDictionary) {
      if (threadDictionary[key].id === threadId) {
        newThread = true;
      }
    }
    return newThread;
  }).first();
}

newThread: boolean = false;

this.knowNewThread(objMessage.id)
  .subscribe( (test: boolean) => {
    if(test === true) {
      this.newThread = true;
    }
});

When the id is already known, I would like to have my variable newThread to false, conversely for an unknown id, I would like the variable newThread to be true.

1
You seem to think of Observable as a collection, or a box containing something. That's not, at all, what it is. An Observable is more like a phone. You turn on the phone (i.e. subscribe to the observable), indicating that you would like to receive phone calls (i.e. events). And some time, later, you receive phone calls (i.e. events). You can't just open the phone and see all the phone calls waiting for you. Sorry, but that's all I can say. You really need to understand what an Observable is about, because what you're trying to do doesn't make sense. - JB Nizet
@JBNizet I really do not know how to go about it. I edited my post by adding details - Floriane
I can't answer. Not without knowing why you're using observables in the first place, what these methods are for, where they're being used, etc. The general way of dealing with observables is to get them from services, subscribe to them in components and store the event they emit in the component, and to work with the data in the component (not with observables). So, if you need to display threads, store the threads in your component (not the Observable) and deal with the threads. - JB Nizet
@JBNizet My thread variable is initailized in a threadService service I then search through these threads to see if the id is already in use or not. I reedited my post - Floriane

1 Answers

1
votes

This should work:

knowNewThread(threadId: string): Observable<boolean> {
  return this.threads
  .map((threadDictionary: { [key: string]: Thread }) => {
    let newThread: boolean = false;
    for (let key in threadDictionary) {
      if (threadDictionary[key].id === threadId) {
        newThread = true;
      }
    }
    return newThread;
  });
}

In your code

return newThread;

will be executed before

for (let key in threadDictionary) { ...

because an Observable is async.