1

I'm not able to return the inner observable

createItem -> Will create the item (POST request) The resposne form that item contains ID , by using that ID I'm adding attachemnts to the Item.

addAttachmentstoItem -> POST request

selected file -> contains attached files in the form , we are looping through each file & calling the addAttachmentstoItem post request.

Merge Map operator for inner observable isn't able to return the observable

this.sharepointService.createItem(this.itemData)
  .pipe(
    mergeMap  (( response : Response) => {
      this.lastItemCreatedId = response['d'].ID
      this.selectedfile.forEach( (file) => {
        let filename = file.name
        let url = "_spPageContextInfo.webAbsoluteUrl"+"_api/web/lists/getByTitle('"+ libraryName +"')/items("+this.lastItemCreatedId+")/AttachmentFiles/add(FileName = '"+filename+"')"
      return this.sharepointService.addAttachementstoItem(url,filename).subscribe( response => console.log("File Uploaded"))
 })
    }),
  ).subscribe()

code in the sharepointService :

 createItem(itemData): Observable<Object> {
 console.log("Inside postItem")
 console.log(itemData.reqno)
  var body = {
    "__metadata" : {'type' : 'SP.Data.CustomListListItem'},
    'Title' : 'first',
    'Requisition_x0020_Number' : itemData.reqno,
    'Site_x0020_Security_x0020_Groups' : itemData.sitesecuritygroups,
    'User_x0020_Security_x0020_Groups' :itemData.usersecuritygroups,
    'Attachments' : itemData.selectedfile
  }
  return this.http.post(this.baseUrl+"_api/web/lists/getbytitle('CustomList')/items",body)
 }

 addAttachementstoItem(url,selectedfile): Observable<Object> {
   console.log(url)
   return this.http.post(url,selectedfile)
 }

I'm getting the error : Argument of type '(response: Response) => void' is not assignable to parameter of type '(value: Response, index: number) => ObservableInput'. Type 'void' is not assignable to type 'ObservableInput'.

1 Answer 1

2

Your callback needs to return an observable, currently it's returning nothing. You can use the forkJoin (https://www.learnrxjs.io/operators/combination/forkjoin.html) operator to create an observable which will emit once all the observables you're creating fron the addAttachmentsToItem complete and return that. Something like the below:

this.sharepointService.createItem(this.itemData)
  .pipe(
    mergeMap(( response : Response) => {
      this.lastItemCreatedId = response['d'].ID
      const obs = this.selectedfile.map((file) => {
        let filename = file.name
        let url = "spPageContextInfo.webAbsoluteUrl"+"_api/web/lists/getByTitle('"+ libraryName +"')/items("+this.lastItemCreatedId+")/AttachmentFiles/add(FileName = '"+filename+"')"
        return this.sharepointService.addAttachementstoItem(url,filename)
       })
       return forkJoin(...obs);
    }),
  ).subscribe()
Sign up to request clarification or add additional context in comments.

8 Comments

Thanks Michael for your suggestion . I have one doubt , we are not subscribing to the second post request method addAttachmentstoItem. Instead of subscribing we are using return. Why is this so ?
you don't need to subscribe to the inner observables, you need to return it as that's what merge map is expecting. You're effectively creating one observable out of two which is why you only need to subscribe once at the end.
After code change , I'm getting this error on return forkJoin(obs); Argument of type 'void' is not assignable to parameter of type 'ObservableInput<unknown>
Have you imported forkJoin from rxjs?
Without seeing the updates you've made, based on the exception I'm guessing you haven't changed the forEach to a map
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.