1

i am using fetch Api to read a local file from my project.

So did some code and, but the issue is that my response from the request is always the previouse one.

 var tmplText = [sometextForReplament]
 var textToBeReplace;
 var enumText = [someText]//as example, here is where the $enum to be replaced  is

  async function ReadFileFromProject() {

  let data = await fetch('/assets/groovy.txt')
       .then(response => response.text())
       .then(data => {

          tmplText.push(data);

         textToBeReplace = tmplText[0];

            if (textToBeReplace.indexOf('$enum') > -1)
            {
                textToBeReplace = textToBeReplace.replace('$enum', enumText);

            }

         console.log(textToBeReplace);
        console.log(filename + 'exported with success');
       })
       .catch(error => {
        alert('Can not read local file:' + error);
          return error;
        });
 }

I thougth the async and wait was to make my asynchronous request to be synchronous not so?

solo
  • 338
  • 4
  • 16
  • 1
    Do you mean that the contents of Groovy.txt are the same for each request? If so, it doesn't look like you actually modify the file itself, just the response. – Matt Evans Jul 17 '19 at 08:23
  • From the code you shared, I can only say, you don't really know what happens in that code block, you are not returning the fetch response, and you are not returning anything from the then chain (at, most `data` would be an error). Other than that, you seem to reuse a local variable as an argument, so it's just confusing... – Icepickle Jul 17 '19 at 08:24
  • @MatthewEvans no. The problem is that the first call of the method ReadFileFromProject() returns and undefined, the second call returns the Groovy.txt correctly. – solo Jul 17 '19 at 08:51
  • @solo you are not returning anything, your function `ReadFileFromProject` doesn't return anything, and your inner then block doesn't return anything (or rather, when not explicitely returning, it returns undefined). You are also not waiting anything, you create a new context for the await operation, but since nothing listens to it finishing, you are completely unaware to what happens. And no, await/async is not ment to make your code synchronous, just ment to make it more readable – Icepickle Jul 17 '19 at 08:54
  • @Icepickle sorry for the vocab "return", i wantaed to say: The problem is that the first call of the method ReadFileFromProject() shows and undefined in the console, the second call shows the Groovy.txt correctly. I am going to revue my code may i am doing something bad – solo Jul 17 '19 at 09:05
  • well, I honestly don't have a clue what your `someTextForReplament` is, and this seems to be the only text in `tmplText` before you push something else in it. The code as you have it, is simply confusing, with global variables, stuff that gets assigned which is just a promise, but nothing gets done with it, no real reusability, there are definitely some things to work on there. To get an answer, you might need to edit more in detail how you call your function, and what is a sample input and expected output ;) – Icepickle Jul 17 '19 at 09:29

1 Answers1

0

I think you really need to work on re-usability and program flow of your methods, there are some things wrong that make it hard to guess what is going on without having a complete example, but I do have a suggested rewrite that gives you an indication how you could refactor it

function getData( url ) {
  return fetch( url )
    .then( response => {
      if ( response.ok ) {
        // return the response itself
        return response;
      }
      // well the response wasn't okay, throw an error, break the chain
      throw '400 Bad request';
   });
}

function replaceContentWithEnumText( url, enumText ) {
  return getData( url )
    // valid data, we want the response as text
    .then( resp => resp.text() )
    // split the text (if any, and join it with enumText)
    .then( text => {
      return text && text.split( '$enum' ).join( enumText );
    } );
}

// note for here it isn't a valid url, so you really wont see anything)
replaceContentWithEnumText( '/assets/groovy.txt', 'someText' )
  // once in the below then, fetch has happened, your text was replaced, you can use replacedContent
  .then( replacedContent => console.log( 'comleted succesfully, data returned would be ', replacedContent ) )
  // something went wrong in the entire chain of events, handling it here makes sense
  .catch( err => console.log( 'error occured', err ) );

If I would go through your original code, for me:

  • I dislike having magical global variables, that get mutated, they really don't help you, you never really know what their state would be...
  • Your function is written with a capital letter, although that could be a guideline, a convention would give funtions lowercased letters to start with
  • You assign let data to await fetch..., at most, data would contain the error message there, because only from the catch block you are actually returning something
  • You don't seem to do anything with the let data variable
  • In your promise chain, you then have a data argument (confusing)
  • Your async/await is completely superfluous, your code doesn't even use it (I know you believe await makes your code synchronous, but well, it's not working as you think it is)

async marked functions will implicitly return a promise. You can await promises, which will then return the response of the promise chain to what ever you assign it. Your code will wait to continue, until the promise runs through (but, not your program, that will continue running).

It is really just syntactic sugar for promises, some say it makes it more readable, but that is entirely opinion based.

Icepickle
  • 12,689
  • 3
  • 34
  • 48
  • Tkhs a lot for the time you took for replying. I am going to take in consideration your ideas. I will back to you after applying what you propose as refacto – solo Jul 17 '19 at 11:29
  • Thks for the advices – solo Jul 31 '19 at 13:46