It seems like some of the example code in the online documentation is not up to date for v3.0.0 yet. I believe that's what is confusing me as I can't seem to get my code to work with v3.0.0.
Please note: I'm not using node.js. I _am_ using JSZipUtils and FileSaver.
I'm getting a TypeError: zip.file(...) is null error on this line zip.file( tgmpaDir + '/example.php' ).async( 'string' ).then( function( content ). The file however does exist within the zip file.
Old code :
var tgmpaDir = 'TGM-Plugin-Activation-2.5.2';
JSZipUtils.getBinaryContent( '../releases/' + tgmpaDir + '.zip', function( err, data ) {
if ( err ) {
showMessage( 'Failed to retrieve TGMPA: ' + err, 'error' );
return false;
}
try {
zip = new JSZip( data );
// Read a file from the zip
exampleFileContent = zip.file( tgmpaDir + '/example.php' ).asText();
// <snip> Adjusting exampleFileContent
// Replace the original file with the new content.
zip.file( tgmpaDir + '/example.php', exampleFileContent );
if ( JSZip.support.blob ) {
try {
blob = zip.generate( { type:'blob' } );
// Uses FileSaver.js.
saveAs( blob, tgmpaDir + '-' + slug + '.zip' );
showMessage( 'Custom TGMPA succesfully created!', 'success' );
} catch ( e ) {
showMessage( 'Failed to generate Custom TGMPA file: ' + e, 'error' );
}
} else {
showMessage( 'This browser is not supported.', 'warning' );
}
return false;
} catch ( e ) {
showMessage( ' ' + e, 'error' );
}
});
New code :
var tgmpaDir = 'TGM-Plugin-Activation-2.5.2';
JSZipUtils.getBinaryContent( '../releases/' + tgmpaDir + '.zip', function( err, data ) {
if ( err ) {
showMessage( 'Failed to retrieve TGMPA: ' + err, 'error' );
return false;
}
try {
zip = new JSZip();
zip.loadAsync( data );
zip.file( tgmpaDir + '/example.php' ).async( 'string' ).then( function( content ) {
// <snip> Adjusting content
// Replace the original file with the new content.
zip.file( tgmpaDir + '/example.php', content );
} );
if ( JSZip.support.blob ) {
try {
zip.generateAsync( { type:'blob' } ).then( function( blob ) {
// Uses FileSaver.js.
saveAs( blob, tgmpaDir + '-' + slug + '.zip' );
showMessage( 'Custom TGMPA succesfully created!', 'success' );
} );
} catch ( e ) {
showMessage( 'Failed to generate Custom TGMPA file: ' + e, 'error' );
}
} else {
showMessage( 'This browser is not supported.', 'warning' );
}
return false;
} catch ( e ) {
showMessage( ' ' + e, 'error' );
}
});
The issue comes from
zip = new JSZip();
zip.loadAsync( data );
zip.file( tgmpaDir + '/example.php' )....
loadAsync is asynchronous: when you try to read example.php, zip is still empty. loadAsync returns a Promise, you need to wait for the result:
JSZip.loadAsync(data).then(function(zip){
// ...
});
The upgrade guide is indeed confusing as it doesn't hint this change (I'll fix that).
You could write the new code like this:
var tgmpaDir = 'TGM-Plugin-Activation-2.5.2';
if ( !JSZip.support.blob ) {
showMessage( 'This browser is not supported.', 'warning' );
return;
}
JSZipUtils.getBinaryContent( '../releases/' + tgmpaDir + '.zip', function( err, data ) {
if ( err ) {
showMessage( 'Failed to retrieve TGMPA: ' + err, 'error' );
return false;
}
JSZip.loadAsync(data).then(function updateContent(zip) {
// replace the original file with a promise of the new content
var updatedContent = zip.file( tgmpaDir + '/example.php' ).async( 'string' ).then( function( content ) {
// <snip> Adjusting content
return newContent;
});
// updatedContent is a promise of string, resolved by JSZip
zip.file( tgmpaDir + '/example.php', updatedContent );
return zip;
}).then(function generateZip(zip) {
return zip.generateAsync( { type:'blob' } );
}).then(function success(blob) {
// Uses FileSaver.js.
saveAs( blob, tgmpaDir + '-' + slug + '.zip' );
showMessage( 'Custom TGMPA succesfully created!', 'success' );
}, function failure(e){
showMessage( 'Failed to generate Custom TGMPA file: ' + e, 'error' );
});
return false;
});
@dduponchel Thank you very much for your response. That's very helpful.
I'll go and run some tests with that.
Do I understand correctly that there is no way anymore to run jsZip without using async and promises ?
In that case you may want to adjust/update the documentation on the following page for the new code structure (still shows three old examples):
https://github.com/Stuk/jszip/blob/gh-pages/documentation/howto/read_zip.md
Do I understand correctly that there is no way anymore to run jsZip without using async and promises ?
That's correct.
I also missed a removed constructor in documentation/api_jszip/file_name.md. Thanks for the hint !
Most helpful comment
That's correct.
I also missed a removed constructor in documentation/api_jszip/file_name.md. Thanks for the hint !